情報アイランド

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

expressモジュールによるHTTPサーバ(5)テキストデータの送信

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

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

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

この記事ではexpressモジュールを使ってHTTPリクエストに対してリクエストメソッドやURLに応じてテキストデータの送信を行うHTTPサーバを作成する方法について説明します。

ルーティングとは

ルーティングとはパスとリクエストメソッドに応じてアプリケーションにミドルウェアを追加することです。

パスとリクエストメソッドの組み合わせをルートと言います。

ルートへのミドルウェアの追加

アプリケーションのルートにミドルウェアを追加するにはリクエストメソッドに応じてapp.get関数、app.post関数、app.put関数、app.delete関数などを使用します。

あるいは、httpモジュールがサポートしている全てのメソッドのリクエストに対して実行されるミドルウェアを追加するにはapp.all関数を使用します。

var express = require('express');

var app = express();
app.get('xxx', function (req, res, next) {
    next();
    //or
    next(new Error('aaa'));
});
app.all('xxx', function (req, res, next) {
    next();
    //or
    next(new Error('aaa'));
});

これらの関数の引数はapp.use関数の引数と同じです。

なお、上の5つの関数以外にもリクエストメソッドに対応して下のような関数があります。

  • app.checkout関数
  • app.copy関数
  • app.head関数
  • app.lock関数
  • app.merge関数
  • app.mkactivity関数
  • app.mkcol関数
  • app.move関数
  • app.m-search関数
  • app.notify関数
  • app.options関数
  • app.patch関数
  • app.purge関数
  • app.report関数
  • app.search関数
  • app.subscribe関数
  • app.trace関数
  • app.unlock関数
  • app.unsubscribe関数

レスポンスステータスの設定

HTTPレスポンスのステータスコードを設定するにはres.status関数を使用します。

app.use(function (req, res, next) {
    res.status(200);
    next();
});

第1引数にステータスコードを指定します。

Content-Typeフィールドの設定

HTTPレスポンスヘッダのContent-Typeフィールドを設定するにはres.type関数を使用します。

app.use(function (req, res, next) {
    res.type('xxx');
    next();
});

第1引数にHTTPレスポンスボディのメディアタイプ(MIMEタイプ)を指定します。

MIMEタイプの代わりに拡張子を指定することもできます。その場合、拡張子に対応するMIMEタイプがContent-Typeフィールドに設定されます。

レスポンスヘッダの設定

HTTPレスポンスヘッダのフィールドを設定するにはres.header関数かres.set関数を使用します。

app.use(function (req, res, next) {
    res.header('xxx', 'yyy');
    //or
    res.header({
        'xxx': 'yyy', 
        'zzz': 'aaa'
    });
    next();
});

第1引数にフィールド名を指定します。

第2引数にフィールドの値を指定します。

あるいは、第1引数に複数のフィールドをオブジェクトとして指定することもできます。このオブジェクトのプロパティ名はフィールド名とし、プロパティの値はフィールドの値とします。

レスポンスヘッダの値の追加

HTTPレスポンスヘッダのフィールドの値を追加するにはres.append関数を使用します。

app.use(function (req, res, next) {
    res.append('xxx', 'yyy');
    next();
});

第1引数にフィールド名を指定します。

第2引数にフィールドの値を指定します。

レスポンスの送信

データを設定しないで送信

HTTPレスポンスボディにデータを何も設定しないでレスポンスの送信を行うにはres.end関数を使用します。

app.use(function (req, res, next) {
    res.end();
});

データを設定して送信

HTTPレスポンスボディにデータを設定してレスポンスの送信を行うにはres.send関数を使用します。

app.use(function (req, res, next) {
    res.send('xxx');
});

第1引数にデータを指定します。バッファ、文字列、オブジェクト、配列を指定することができます。

HTTPレスポンスヘッダのContent-Typeフィールドが設定されていない場合には第1引数のデータの種類に応じて下のように設定されます。

  • バッファ・・・application/octet-stream
  • 文字列・・・text/html; charset=utf-8
  • オブジェクト・・・application/json; charset=utf-8
  • 配列・・・application/json; charset=utf-8

ステータスコードを設定して送信

HTTPレスポンスステータスコードを設定し、HTTPレスポンスボディにステータスコードに対応するステータスメッセージを設定してレスポンスの送信を行うにはres.sendStatus関数を使用します。

app.use(function (req, res, next) {
    res.sendStatus(200);
});

第1引数にステータスコードを指定します。

サンプルコード1

クライアントからリクエストを受け取ったらリクエストメソッドやURLに応じて様々なテキストデータを返すHTTPサーバを作成し、起動します。

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

express-server-text.js

var express = require('express');
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.status(200);
    res.type('text/plain; charset=utf-8');
    next();
});
app.get('/', function (req, res, next) {
    res.send('welcome to pizyumi\'s website. this is home page.\r\n');
});
app.get('/author', function (req, res, next) {
    res.send('author is pizyumi.\r\n');
});
app.get('/hello', function (req, res, next) {
    res.send('this is hello page.\r\n');
});
app.get('/hello/*', function (req, res, next) {
    res.send('hello, ' + req.path.split('/')[2] + '.\r\n');
});
app.get('*', function (req, res, next) {
    res.status(404);
    res.send(http.STATUS_CODES[404] + '\r\n');
});
app.post('*', function (req, res, next) {
    res.send('request method is post.\r\n');
});
app.all('*', function (req, res, next) {
    res.status(501);
    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でインストールします。

実行結果

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

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

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

cURLを使ってサーバに対して様々なメソッドやURLのHTTPリクエストを行います。

C:\work\node>curl -v http://localhost:3000/
*   Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.46.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/plain; charset=utf-8
< Content-Length: 50
< ETag: W/"32-juTlohfTcZy04HpD+lfkLw"
< Date: Sun, 10 Jul 2016 04:12:18 GMT
< Connection: keep-alive
<
welcome to pizyumi's website. this is home page.
* Connection #0 to host localhost left intact
C:\work\node>curl -v http://localhost:3000/author
*   Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> GET /author HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.46.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/plain; charset=utf-8
< Content-Length: 20
< ETag: W/"14-sE0PITZfvap0ovAO45JijA"
< Date: Sun, 10 Jul 2016 04:12:49 GMT
< Connection: keep-alive
<
author is pizyumi.
* Connection #0 to host localhost left intact
C:\work\node>curl -v http://localhost:3000/hello
*   Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> GET /hello HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.46.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/plain; charset=utf-8
< Content-Length: 21
< ETag: W/"15-xhKWA7hChdETvI9jE3nj4A"
< Date: Sun, 10 Jul 2016 04:13:10 GMT
< Connection: keep-alive
<
this is hello page.
* Connection #0 to host localhost left intact
C:\work\node>curl -v http://localhost:3000/hello/
*   Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> GET /hello/ HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.46.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/plain; charset=utf-8
< Content-Length: 10
< ETag: W/"a-qbyWFmGWhW+VcOsP2I/dOw"
< Date: Sun, 10 Jul 2016 04:13:27 GMT
< Connection: keep-alive
<
hello, .
* Connection #0 to host localhost left intact
C:\work\node>curl -v http://localhost:3000/hello/irori
*   Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> GET /hello/irori HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.46.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/plain; charset=utf-8
< Content-Length: 15
< ETag: W/"f-Oo41ZDgIaQynIT5QucZLDA"
< Date: Sun, 10 Jul 2016 04:13:45 GMT
< Connection: keep-alive
<
hello, irori.
* Connection #0 to host localhost left intact
C:\work\node>curl -v http://localhost:3000/hello/irori/suki
*   Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> GET /hello/irori/suki HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.46.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/plain; charset=utf-8
< Content-Length: 15
< ETag: W/"f-Oo41ZDgIaQynIT5QucZLDA"
< Date: Sun, 10 Jul 2016 04:14:01 GMT
< Connection: keep-alive
<
hello, irori.
* Connection #0 to host localhost left intact
C:\work\node>curl -v http://localhost:3000/qqq
*   Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> GET /qqq HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.46.0
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Content-Type: text/plain; charset=utf-8
< Content-Length: 11
< ETag: W/"b-+G1N6c4TYEJWpLR8VMBCIA"
< Date: Sun, 10 Jul 2016 04:14:20 GMT
< Connection: keep-alive
<
Not Found
* Connection #0 to host localhost left intact
C:\work\node>curl -v http://localhost:3000/ -X POST
*   Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> POST / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.46.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/plain; charset=utf-8
< Content-Length: 25
< ETag: W/"19-NFNImGKh6Pma/7N1pfmbxg"
< Date: Sun, 10 Jul 2016 04:16:57 GMT
< Connection: keep-alive
<
request method is post.
* Connection #0 to host localhost left intact
C:\work\node>curl -v http://localhost:3000/ -X DELETE
*   Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> DELETE / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.46.0
> Accept: */*
>
< HTTP/1.1 501 Not Implemented
< Content-Type: text/plain; charset=utf-8
< Content-Length: 17
< ETag: W/"11-R+TWVhhFPy+QpmO5hhOsTA"
< Date: Sun, 10 Jul 2016 04:17:28 GMT
< Connection: keep-alive
<
Not Implemented
* Connection #0 to host localhost left intact

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

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

関連

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

-express, Node.js