form-data
を使う。
Axios
const axios = require("axios");
const FormData = require("form-data");
const form = new FormData();
form.append("message", "hello");
const res = await axios.post(API, form, {
headers: form.getHeaders()
});
node-fetch
const fetch = require("node-fetch");
const FormData = require("form-data");
const form = new FormData();
form.append("message", "helllo");
const res = await fetch(API, {
method: "POST",
body: form
});
なぜ node-fetch
はヘッダーでgetHeaders()
を利用しなくていいのか?
理由は単純で、form-data
を特別に扱っている。
https://github.com/node-fetch/node-fetch/blob/c167190c6ee21234ba41bd8430700d4720bf64ce/src/body.js#L320-L323
// Detect form data input from form-data module
if (body && typeof body.getBoundary === 'function') {
return `multipart/form-data;boundary=${body.getBoundary()}`;
}
さて、multipart/form-data;
はいいにしても、boundary
とはなんだろうか。
boundary
とは、複数の情報を続けて送る際、データの仕切り線の役割を果たす。
form-data
の実装を見ると、-
が26文字、ランダムな数値が24字の50文字の仕切り線を生成する。
FormData.prototype._generateBoundary = function() {
// This generates a 50 character boundary similar to those used by Firefox.
// They are optimized for boyer-moore parsing.
var boundary = '--------------------------';
for (var i = 0; i < 24; i++) {
boundary += Math.floor(Math.random() * 10).toString(16);
}
this._boundary = boundary;
};
これに\r\n
を付加したものを区切りにする。
詳しくは、以下の記事に詳しい。