node-fetchでPOSTがうまくできなかった記録


背景

I always use http://github.com/github/fetch for browser and node-fetch for node ができるといいな、と思って、node-fetchを試してみました。

結論

サーバーによって上手く行ったり行かなかったりします。

node-fetchのサンプルコード

宛先は http://httpbin.org/ です。
httpbinは/POSTにデータを送ると、そのまま送り返えしてきます。

node_fetch_example.js
var fetch = require('node-fetch');

fetch('http://httpbin.org/post', {
    method: 'POST',
    body: 'a=1'
  })
  .then(function(res) {
    return res.json();
  }).then(function(json) {
    console.log(json);
  });

実行例

node node_fetch_example.js
{ args: {},
  data: 'a=1',
  files: {},
  form: {},
  headers:
   { Accept: '*/*',
     'Accept-Encoding': 'gzip,deflate',
     'Content-Length': '3',
     Host: 'httpbin.org',
     'User-Agent': 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)' },
  json: null,
  origin: '126.186.244.59',
  url: 'http://httpbin.org/post' }

dataがa=1で、送信できています。

RequestBin

RequestBinは、HTTPリクエストの中身を調査するための送り先URLを作成してくれるサービスです。こちらで用意したURLに送ってみます。

request_bin_example.js
var fetch = require('node-fetch');

fetch('http://requestb.in/y5m0fiy5', {
    method: 'POST',
    body: 'a=1'
  });

実行結果

BodyはNoneと表示されます。

echoサーバー

試しに自分でechoサーバーを動かしてみます。

echoServer.js
var http = require('http');

http
  .createServer(function(req, res) {
    req.pipe(res);
  })
  .listen(3000);

クライアントのレスポンス処理をres.jsonres.txetに変更します。

var fetch = require('node-fetch');

fetch('http://localhost:3000', {
    method: 'POST',
    body: 'a=1'
  })
  .then(function(res) {
    return res.text();
  }).then(function(json) {
    console.log(json);
  });

実行結果

~ node example3.js
a=1

補足

res.jsonを使う時は、送信側もJSON.stringifyを使います。

var fetch = require('node-fetch');

fetch('http://localhost:3000', {
    method: 'POST',
    body: JSON.stringify('a=1')
  })
  .then(function(res) {
    return res.json();
  }).then(function(json) {
    console.log(json);
  });

感想

自分でサーバーを書かかない時は、superagent使うのが無難と思います。

参考