如何使用带有本机Node.js https.request的multipart / form-data标头上传文件?

时间:2017-11-30 02:44:32

标签: node.js multipartform-data

我正在尝试使用来自node.js的原生https.request从我的计算机上传文件。我的代码看起来像这样:

let query = require('https').request({
  hostname: 'somehost.com',
  path: '/path/to/upload',
  headers: {'Content-Type': 'multipart/form-data'},
  method: 'POST'
}, (res) => {
  let data = '';
  res.on("data", (chunk) => {
    data += chunk.toString('utf8');
  });
  res.on('end', () => {
    console.log("data");
  })
});
query.on("error", (e) => {
  console.error(e);
});
query.write(Buffer[
  {key1: 1, file: require("fs").createReadStream("/path/to/file.txt")}
]);      // I don't know how to put here
query.end();

我没有得到主机的任何回复,文件上传失败。我怎么能这样做?

1 个答案:

答案 0 :(得分:1)

上传多部分/表单数据时,Content-Type标题必须包含boundary,以便指明每个"部分"生活在发布的数据中。要设置The Multipart Content-Type的边界,您可以使用NPM中的form-data包。您可以 set the header/boundary manually,但表单数据包将为您处理此问题,让您不必担心细节等。

要在示例中使用表单数据,您需要执行以下操作:

  1. 创建新的FormData对象和append相关部分:

    let formData = new require('form-data')();
    formData.append('key1', 1);
    formData.append('file', require("fs").createReadStream("/path/to/file.txt"));
    
  2. 使用getHeaders函数构建正确的HTTP标头:

    require('https').request({
        headers: formData.getHeaders(),
        // ...
    }
    
  3. 使用pipe以允许表单数据处理您的数据并将其发送到服务器:

    formData.pipe(query);
    

    通过此更改,您不再需要拨打query.writequery.end - 致电pipe即可解决此问题。

  4. 为了完整起见,这里是我所描述的更改的最终代码:

    let formData = new require('form-data')();
    formData.append('key1', 1);
    formData.append('file', require("fs").createReadStream("/path/to/file.txt"));
    
    let query = require('https').request({
        hostname: 'somehost.com',
        path: '/path/to/upload',
        method: 'POST',
        headers: formData.getHeaders()
    }, (res) => {
        let data = '';
        res.on("data", (chunk) => {
            data += chunk.toString('utf8');
        });
        res.on('end', () => {
            console.log(data);
        })
    });
    
    query.on("error", (e) => {
        console.error(e);
    });
    
    formData.pipe(query);