我在Node.js中使用POST请求上传文件时遇到问题。我必须使用request
模块来完成它(没有外部的npms)。服务器需要使用包含文件数据的file
字段进行多部分请求。在没有使用任何外部模块的情况下,在Node.js中做起来似乎很容易。
我尝试使用this example但未成功:
request.post({
uri: url,
method: 'POST',
multipart: [{
body: '<FILE_DATA>'
}]
}, function (err, resp, body) {
if (err) {
console.log('Error!');
} else {
console.log('URL: ' + body);
}
});
答案 0 :(得分:89)
看起来您已经在使用request
module。
在这种情况下,您需要发布multipart/form-data
即可使用其form
feature:
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
的详细信息,请参阅request
内部使用的node-form-data
module。
答案 1 :(得分:17)
formData
实现的request
字段的未记录功能是将选项传递给它使用的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
选项。
This change于2014年10月被添加(因此在询问此问题后2个月),因此现在可以安全使用(2017年以上)。这相当于v2.46.0
的版本request
或更高版本。
答案 2 :(得分:4)
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
});
答案 3 :(得分:4)
您还可以使用&#34;自定义选项&#34;来自请求库的支持。此格式允许您创建多部分表单上载,但具有文件和额外表单信息的组合条目,如文件名或内容类型。我发现有些库希望使用这种格式接收文件上传,特别是像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);
}
});
答案 4 :(得分:0)
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);