How to send file in node-fetch or Node request?

How do I attach a file in a Node or Node Fetch POST request? I am trying to call an API that will import a CSV or XLS file. Is this possible with Node or Node Fetch?

+12
source share
4 answers

README.md says:

Use your own body stream for both request and response.

And sources indicate that it supports several types , for example Stream , Buffer , Blob ... and will also try coerce as String for other types.

Below the fragment 3 examples are shown, all work with v1.7.1 or 2.0.0-alpha5 (see also another example further with FormData ):

 let fetch = require('node-fetch'); let fs = require('fs'); const stats = fs.statSync("foo.txt"); const fileSizeInBytes = stats.size; // You can pass any of the 3 objects below as body let readStream = fs.createReadStream('foo.txt'); //var stringContent = fs.readFileSync('foo.txt', 'utf8'); //var bufferContent = fs.readFileSync('foo.txt'); fetch('http://httpbin.org/post', { method: 'POST', headers: { "Content-length": fileSizeInBytes }, body: readStream // Here, stringContent or bufferContent would also work }) .then(function(res) { return res.json(); }).then(function(json) { console.log(json); }); 

Here is foo.txt :

 hello world! how do you do? 

Note. http://httpbin.org/post responds with JSON, which contains the details of the request.

Result:

 { "args": {}, "data": "hello world!\nhow do you do?\n", "files": {}, "form": {}, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip,deflate", "Connection": "close", "Content-Length": "28", "Host": "httpbin.org", "User-Agent": "node-fetch/1.0 (+https://github.com/bitinn/node-fetch)" }, "json": null, "origin": "86.247.18.156", "url": "http://httpbin.org/post" } 

If you need to submit a file as part of a form with a lot of parameters, you can try:

  • npm install form-data
  • pass the FormData object as a body ( FormData is a Stream view, through the CombinedStream library )
  • do not skip header in parameters (unlike above examples)

and then it works:

 const formData = new FormData(); formData.append('file', fs.createReadStream('foo.txt')); formData.append('blah', 42); fetch('http://httpbin.org/post', { method: 'POST', body: formData }) 

Result (just showing what was sent):

 ----------------------------802616704485543852140629 Content-Disposition: form-data; name="file"; filename="foo.txt" Content-Type: text/plain hello world! how do you do? ----------------------------802616704485543852140629 Content-Disposition: form-data; name="blah" 42 ----------------------------802616704485543852140629-- 
+22
source

I was looking for how to use node-fetch to upload files via multipart/form-data , and their GitHub docs actually show how to do this . The following is a modified example showing how to attach a buffer to FormData and load it.

 const FormData = require('form-data'); const form = new FormData(); const buffer = // eg 'fs.readFileSync('./fileLocation'); const fileName = 'test.txt'; form.append('file', buffer, { contentType: 'text/plain', name: 'file', filename: fileName, }); fetch('https://httpbin.org/post', { method: 'POST', body: form }) .then(res => res.json()) .then(json => console.log(json)); 

I am sharing this with someone else who has google "node-fetch upload file multipart" like me.

+3
source

This is an express server that sends a local file in response.

 var fs = require('fs'); var express = require('express')(); express.get('/',function(req,res){ var readStream = fs.createReadStream('./package.json'); readStream.pipe(res); }) express.listen(2000); 
-2
source

There is one thing to add to the Hugues M. answer. File upload using FormData not supported by node-fetch . Instead, you need to use other libraries, such as request or request-promise . The following is a snippet of code to download a file using the request-promise library. resolveWithFullResponse gives a raw response. Without this, a promise returns only the body of the response.

 let rp = require('request-promise') var formData = { file: fs.createReadStream('foo.txt'), } let options = { uri:'http://httpbin.org/post', formData: formData, resolveWithFullResponse: true } rp.post(options).then((response) => { // handle response here }) 
-2
source

All Articles