繁体   English   中英

在 Node.js 中使用 POST 请求上传文件

[英]Uploading file using POST request in Node.js

我在 Node.js 中使用 POST 请求上传文件时遇到问题。我必须使用request模块来完成(没有外部 npms)。 服务器需要它是包含文件数据的file字段的多部分请求。 在 Node.js 中,不使用任何外部模块就很难做到看似简单的事情。

我试过使用这个例子但没有成功:

request.post({
  uri: url,
  method: 'POST',
  multipart: [{
    body: '<FILE_DATA>'
  }]
}, function (err, resp, body) {
  if (err) {
    console.log('Error!');
  } else {
    console.log('URL: ' + body);
  }
});

看起来您已经在使用request module

在这种情况下,您只需发布multipart/form-data即可使用其form功能

var req = request.post(url, function (err, resp, body) {
  if (err) {
    console.log('Error!');
  } else {
    console.log('URL: ' + body);
  }
});
var form = req.form();
form.append('file', '<FILE_DATA>', {
  filename: 'myfile.txt',
  contentType: 'text/plain'
});

但是如果你想从你的文件系统中发布一些现有的文件,那么你可以简单地将它作为可读流传递:

form.append('file', fs.createReadStream(filepath));

request将自行提取所有相关元数据。

有关发布multipart/form-data更多信息,请参阅node-form-data模块,该模块request内部使用。

request实现的formData字段的一个未记录的功能是能够将选项传递给它使用的form-data模块:

request({
  url: 'http://example.com',
  method: 'POST',
  formData: {
    'regularField': 'someValue',
    'regularFile': someFileStream,
    'customBufferFile': {
      value: fileBufferData,
      options: {
        filename: 'myfile.bin'
      }
    }
  }
}, handleResponse);

如果您需要避免调用requestObj.form()但需要将缓冲区作为文件上传,这将非常有用。 form-data模块还接受contentType (MIME 类型)和knownLength选项。

此更改于 2014 年 10 月添加(因此在提出此问题后 2 个月),因此现在使用应该是安全的(在 2017 年以上)。 这等同于版本v2.46.0或以上的request

Leonid Beschastny 的回答有效,但我还必须将 ArrayBuffer 转换为 Node request模块中使用的 Buffer。 将文件上传到服务器后,我使用了与 HTML5 FileAPI 相同的格式(我使用的是 Meteor)。 下面的完整代码 - 也许对其他人有帮助。

function toBuffer(ab) {
  var buffer = new Buffer(ab.byteLength);
  var view = new Uint8Array(ab);
  for (var i = 0; i < buffer.length; ++i) {
    buffer[i] = view[i];
  }
  return buffer;
}

var req = request.post(url, function (err, resp, body) {
  if (err) {
    console.log('Error!');
  } else {
    console.log('URL: ' + body);
  }
});
var form = req.form();
form.append('file', toBuffer(file.data), {
  filename: file.name,
  contentType: file.type
});

您还可以使用请求库中的“自定义选项”支持。 此格式允许您创建多部分表单上传,但包含文件和额外表单信息(如文件名或内容类型)的组合条目。 我发现一些库希望使用这种格式接收文件上传,特别是像 multer 这样的库。

这种方法正式记录在请求文档的表单部分 - https://github.com/request/request#forms

//toUpload is the name of the input file: <input type="file" name="toUpload">

let fileToUpload = req.file;

let formData = {
    toUpload: {
      value: fs.createReadStream(path.join(__dirname, '..', '..','upload', fileToUpload.filename)),
      options: {
        filename: fileToUpload.originalname,
        contentType: fileToUpload.mimeType
      }
    }
  };
let options = {
    url: url,
    method: 'POST',
    formData: formData
  }
request(options, function (err, resp, body) {
    if (err)
      cb(err);

    if (!err && resp.statusCode == 200) {
      cb(null, body);
    }
  });

我是这样做的:

// Open file as a readable stream
const fileStream = fs.createReadStream('./my-file.ext');

const form = new FormData();
// Pass file stream directly to form
form.append('my file', fileStream, 'my-file.ext');
 const remoteReq = request({
    method: 'POST',
    uri: 'http://host.com/api/upload',
    headers: {
      'Authorization': 'Bearer ' + req.query.token,
      'Content-Type': req.headers['content-type'] || 'multipart/form-data;'
    }
  })
  req.pipe(remoteReq);
  remoteReq.pipe(res);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM