在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
是使用其form
function :
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); } });