簡體   English   中英

在 Node.js 中使用 POST 請求上傳文件

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM