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

我在使用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模块了 。

在这种情况下,所有你需要发布multipart/form-data是使用其formfunction :

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

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

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

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

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

request实现的formData字段的未formData的function是将选项传递给它所使用的form-data模块的function:

 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 (MIMEtypes)和knownLength选项。

这个改变是在2014年10月增加的(所以在提出这个问题之后的2个月),所以现在应该是安全的(在2017+以上)。 这相当于v2.46.0或更高版本的request

Leonid Beschastny的答案有效,但我也必须将ArrayBuffer转换为在Node的request模块中使用的Buffer。 将file upload到服务器后,我使用了来自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 }); 

你可以使用这个:

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