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

南笙酒味 提交于 2019-12-03 03:17:54

README.md says:

Use native stream for body, on both request and response.

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

Below snippet shows 3 examples, all work, with v1.7.1 or 2.0.0-alpha5 (see also other example further down 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 replies with JSON that contains details on request that was sent.

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 send a file as part of a form with more parameters, you can try:

  • npm install form-data
  • pass a FormData object as body (FormData is a kind of Stream, via CombinedStream library)
  • do not pass header in the options (unlike examples above)

and then this 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 is 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--
Rico Kahler

I was looking for how to use node-fetch to upload files via multipart/form-data and their GitHub docs actually shows how to do this. Below is modified example showing how to attach a buffer to FormData and upload that.

const FormData = require('form-data');     
const form = new FormData();

const buffer = // e.g. `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));

Sharing this for anyone else who googled "node-fetch upload file multipart" like I did.

This is a express server that streams a local file to the 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);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!