[英]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.