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