Node.jsでPOSTリクエストを使用してファイルをアップロードする際に問題があります。 request
モジュールを使用してそれを達成する必要があります(外部npmはありません)。サーバーは、ファイルのデータを含む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
module を参照してください。これはrequest
によって内部的に使用されます。
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
オプションも受け入れます。
この変更 は2014年10月に追加されたため(この質問が出されてから2か月後)、今は安全に使用できるはずです(2017年以降)。これは、request
のバージョンv2.46.0
以上に相当します。
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);
}
});