情報アイランド

「情報を制する者は世界を制す」をモットーに様々な情報を提供することを目指すブログです。現在はプログラミング関連情報が多めですが、投資関連情報も取り扱っていきたいです。

expressモジュールによるHTTPサーバ(22)リクエストボディ(body-parserモジュール)

2017/06/13

この記事は「expressモジュールによるHTTPサーバ」という連載記事の22つ目の記事です。

その他の記事に関しては下を参照してください。

また、HTTP自体について知りたい方は下を参照してください。

この記事ではexpressモジュールとbody-parserモジュールを使ってHTTPリクエストボディを処理するHTTPサーバを作成する方法について説明します。

HTTPリクエストボディ

HTTPリクエストボディのデータを取得するには下のようなモジュールを利用する方法があります。

  • body-parser
  • multer

この記事ではbody-parserモジュールを利用する方法を取り上げます。

ただし、body-parserモジュールはメディアタイプ(MIMEタイプ)がmultipart/form-dataのデータには対応していませんので注意してください。

メディアタイプがmultipart/form-dataのデータを取得するにはbody-parserモジュールの代わりにmulterモジュールを利用します

body-parserモジュール

HTTPリクエストボディのデータを取得するミドルウェアを作成するにはデータの種類に応じて下のような関数を使用します。

  • bodyParser.raw・・・データをバッファとして取得するミドルウェアを作成します。
  • bodyParser.text・・・データを文字列として取得するミドルウェアを作成します。
  • bodyParser.json・・・データをJSONとして(JSON.parse関数を使用して)取得するミドルウェアを作成します。
  • bodyParser.urlencoded・・・メディアタイプがapplication/x-www-form-urlencodedのデータをオブジェクトとして取得するミドルウェアを作成します。このオブジェクトのプロパティ名はデータのパラメータの名称となり、プロパティの値はパラメータの値となります。
var express = require('express');
var bodyParser = require('body-parser');

var app = express();
app.use(bodyParser.raw({
    inflate: true, 
    limit: '100kb', 
    type: 'application/octet-stream', 
    verify: function (req, res, buf, encoding) {
    }
}));
app.use(bodyParser.text({
    inflate: true, 
    limit: '100kb', 
    type: 'text/plain', 
    verify: function (req, res, buf, encoding) {
    }, 
    defaultCharset: 'utf-8'
}));
app.use(bodyParser.json({
    inflate: true, 
    limit: '100kb', 
    type: 'application/json', 
    verify: function (req, res, buf, encoding) {
    }, 
    reviver: function (k, v) {
    }, 
    strict: true
}));
app.use(bodyParser.urlencoded({
    inflate: true, 
    limit: '100kb', 
    type: 'application/x-www-form-urlencoded', 
    verify: function (req, res, buf, encoding) {
    }, 
    extended: true, 
    parameterLimit: 1000
}));

第1引数にオプションを指定します。

主なオプションには下のようなものがあります。

  • inflate・・・データが圧縮されている場合に解凍するかを真偽値として指定します。デフォルトはtrueです。
  • limit・・・データの最大サイズをバイト単位で整数として指定します。あるいは、単位付きのバイト数を文字列として指定することもできます。単位はbytesモジュールの単位と同一です。デフォルトは100kbです。
  • type・・・拡張子かメディアタイプかワイルドカードを含むメディアタイプを指定します(ワイルドカードを含むメディアタイプとはtext/**/jsonのようなもののことです)。HTTPリクエストのContent-Typeヘッダフィールドの値がこの値に当て嵌まる場合にはデータが取得されます。当て嵌まらない場合にはデータは取得されません。あるいは、関数を指定することもできます。この関数の第1引数はreqです。この関数ではデータの取得を行うかを真偽値として返すようにします。デフォルトはbodyParser.raw関数の場合にはapplication/octet-streamであり、bodyParser.text関数の場合にはtext/plainであり、bodyParser.json関数の場合にはapplication/jsonであり、bodyParser.urlencoded関数の場合にはapplication/x-www-form-urlencodedです。
  • verify・・・データが妥当であるかを検証する関数を指定します。この関数の第1引数はreqであり、第2引数はresであり、第3引数はデータを格納しているバッファであり、第4引数はデータの文字コードです。この関数ではデータが妥当でない場合に例外を投げるようにします。
  • defaultCharset・・・データのデフォルトの文字コードを指定します。HTTPリクエストのContent-Typeヘッダフィールドの値に文字コードが指定されていない場合にはこの文字コードが使用されます。デフォルトはutf-8です。このオプションはbodyParser.text関数でしか使用できません
  • reviver・・・JSON.parse関数の第2引数として使用する値を指定します。このオプションはbodyParser.json関数でしか使用できません
  • strict・・・データが必ずJSONの配列かオブジェクトでなければならないかを真偽値として指定します。デフォルトはtrueです。このオプションはbodyParser.json関数でしか使用できません
  • extended・・・メディアタイプがapplication/x-www-form-urlencodedのデータをパースするためにquerystringモジュールを使用するかqsモジュールを使用するかを真偽値として指定します。querystringモジュールを使用する場合にはfalseを指定し、qsモジュールを使用する場合にはtrueを指定します。デフォルトはtrueです。このオプションはbodyParser.urlencoded関数でしか使用できません
  • parameterLimit・・・メディアタイプがapplication/x-www-form-urlencodedのデータのパラメータの最大数を指定します。デフォルトは1000です。このオプションはbodyParser.urlencoded関数でしか使用できません

返り値としてミドルウェアが得られます。

このミドルウェアはHTTPリクエストボディのデータをreq.bodyに格納します(ただし、HTTPリクエストボディにデータが存在しない場合やデータが処理できなかった場合には空のオブジェクトを格納します)。

サンプルコード1

クライアントからPOSTリクエストを受け取ったらURLに応じてボディのデータを処理し、JSONデータを返すHTTPサーバを作成し、起動します。

Enterキーが押されたらサーバを停止し、プログラムを終了します。

express-server-body-parser.js

var express = require('express');
var bodyParser = require('body-parser');
var http = require('http');

var app = express();
app.set('env', 'development');
app.set('x-powered-by', false);
app.set('case sensitive routing', true);
app.set('strict routing', true);
app.use(function (req, res, next) {
    res.type('text/plain; charset=utf-8');
    next();
});
app.post('/json', bodyParser.json(), function (req, res, next) {
    if (!req.body) {
        res.status(400);
        res.send(http.STATUS_CODES[400] + '\r\n');
    }
    else {
        res.status(200);
        res.json(req.body);
    }
});
app.post('/urlencoded', bodyParser.urlencoded({ extended: false }), function (req, res, next) {
    if (!req.body) {
        res.status(400);
        res.send(http.STATUS_CODES[400] + '\r\n');
    }
    else {
        res.status(200);
        res.json(req.body);
    }
});
app.post('*', function (req, res, next) {
    res.status(404);
    res.type('text/plain; charset=utf-8');
    res.send(http.STATUS_CODES[404] + '\r\n');
});
app.all('*', function (req, res) {
    res.status(501);
    res.type('text/plain; charset=utf-8');
    res.send(http.STATUS_CODES[501] + '\r\n');
});
var server = app.listen(3000, function () {
    console.log('http server is running...press enter key to exit.');

    process.stdin.on('data', function (data) {
        if (data.indexOf('\n') !== -1) {
            server.close(function () {
                console.log('http server closed.');
                process.exit(0);
            });
        }
    });
});
server.on('error', function (err) {
    console.error(err);
    process.exit(1);
});

使用パッケージ

  • express
    npm install expressでインストールします。
  • body-parser
    npm install body-parserでインストールします。

実行結果

実行結果の確認のためにAdvanced REST clientを使用しています。

コードを実行するとHTTPサーバが起動します。

C:\work\node>node express-server-body-parser.js
http server is running...press enter key to exit.

Advanced REST clientを使ってサーバに対して様々なURLのHTTPリクエストを行います。

サーバから正しくレスポンスが返っていることが分かります。

Enterキーを押すとサーバが停止し、プログラムが終了します。

関連

pizyumi
プログラミング歴19年のベテランプログラマー。業務システム全般何でも作れます。現在はWeb系の技術を勉強中。
スポンサーリンク

-express, Node.js