如何在请求node-fetch或nodejs中发送文件

时间:2017-05-17 09:57:10

标签: node.js node-fetch

如何在nodejs / node-fetch POST请求中附加文件。我想调用导入文件的API(.xls或csv)。我怎么能使用Node-fetch / nodejs来做到这一点。

4 个答案:

答案 0 :(得分:16)

README.md说:

  

在请求和响应上使用本机流作为正文。

sources indicate it supports several types一样,StreamBufferBlob ...也会尝试强制为其他类型的String

下面的代码段显示了3个示例,所有工作都是v1.7.1或2.0.0-alpha5(另请参见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);
});

以下是foo.txt

hello world!
how do you do?

注意:http://httpbin.org/post使用JSON回复,其中包含有关已发送请求的详细信息。

结果:

{
  "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"
}

如果您需要将文件作为包含更多参数的表单的一部分发送,您可以尝试:

  • npm install form-data
  • 传递FormData对象作为正文(FormDataStream,通过CombinedStream library
  • 不在选项中传递header(与上述示例不同)

然后这可行:

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

结果(只显示发送的内容):

----------------------------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--

答案 1 :(得分:0)

我一直在寻找如何使用node-fetch通过multipart/form-datatheir GitHub docs actually shows how to do this上传文件。以下是修改后的示例,显示了如何将缓冲区附加到FormData并上传。

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

const buffer = // e.g. `fs.readFileSync('./fileLocation');
const fileName = 'test.txt';

const form = new FormData();
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));

像我一样,将其共享给通过Google搜索“多节点上传文件”的其他人。

答案 2 :(得分:-1)

这是一个快速服务器,它将本地文件流式传输到响应中。

.button_slidehr {
  color: #156466;
  border: 1px solid rgba(21,100,102,0.35);
  border-radius: 0px;
  /* extend left padding */
  padding: 18px 15px 18px 62px;
  position: relative;
  display: inline-block;
  font-family: Verdana;
  font-size: 14px;
  margin-bottom: 20px;
  letter-spacing: 1px;
  background-color: rgba(255,255,255,0.3);
  cursor: pointer;
  box-shadow: inset 0 0 0 0 #156466;
  -webkit-transition: ease-out 0.4s;
  -moz-transition: ease-out 0.4s;
  transition: ease-out 0.4s;
}

.slide_downhr:hover {
  color:white;
  border: 1px solid transparent;
  box-shadow: inset 0 100px 0 0 #156466;
}

.button_slidehr:after {
  content: "";
  display: inline-block;
  position: absolute;
  left: 10px;
  top: 0;
  width: 100%;
  height: 100%;
  background-image: url(http://res.cloudinary.com/djxai1v1e/image/upload/v1498058230/HR-Connect-Logo_hjbrmn.png);
  background-position: left center;
  background-repeat: no-repeat;
  background-size: auto 80%;
}

答案 3 :(得分:-1)

有一件事要添加到 Hugues M。的答案中。 FormData不支持使用node-fetch上传文件。相反,您需要使用其他库,例如requestrequest-promise。以下是使用request-promise库上传文件的代码段。 resolveWithFullResponse选项为您提供原始响应。如果没有这个,承诺只会返回响应的主体。

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 
})