Загрузка файла с помощью запроса POST в Node.js
У меня есть проблема с загрузкой файла с помощью запроса POST в Node.js. Я должен использовать модуль 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);
}
});
Ответы
Ответ 1
Похоже, вы уже используете 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
.
Ответ 2
Недокументированная функция поля 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 года (через 2 месяца после того, как этот вопрос был задан), поэтому его следует использовать в безопасном режиме (в 2017+). Это соответствует версии v2.46.0
или выше request
.
Ответ 3
Ответ Leonid Beschastny работает, но мне также пришлось преобразовать ArrayBuffer в буфер, который используется в модуле Node request
. После загрузки файла на сервер у меня был он в том же формате, что и в файле 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
});
Ответ 4
вы можете использовать это:
//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);
}
});