Node.jsを学ぶ(その4・クエリ文字列で処理を分ける)

  • 投稿日:
  • by
  • カテゴリ:

動的な処理を行うWebページでは、クエリ文字列(URLの「?」から後の部分)で処理を分けることがよくあります。
今日は、Node.jsでクエリ文字列に応じて処理を分ける方法を紹介します。

1.parseメソッドでクエリ文字列をパースする

昨日紹介したparseメソッドを使うと、クエリ文字列をパースすることもできます。
parseメソッドの2つ目のパラメータにtrueを渡すと、「名前1=値1&名前2=値2・・・」のようなクエリ文字列をパースして、オブジェクトに変換します。
その結果が、parseメソッドの戻り値のqueryプロパティに代入されます。

例えば、パース前のクエリ文字列が「abc=def&ghi=123」のようになっていたとします。
この場合、parseメソッドの戻り値のqueryプロパティは、以下のようなオブジェクトになります。

{ 'abc': 'def', 'ghi': '123' }

なお、クエリ文字列に同じ名前が複数回含まれる場合は、そのパース結果は配列になります。
例えば、パース前のクエリ文字列が「foo=bar&foo=baz」のようになっていたとします。
この場合、parseメソッドの戻り値のqueryプロパティは、以下のようなオブジェクトになります。

{ 'foo': [ 'bar', 'baz' ] }

2.事例

昨日のプログラムを修正して、「http://localhost/hello」にアクセスされたときに、以下のようにレスポンスを変えるようにしてみます。

条件レスポンス
「name=○○○」のクエリ文字列が指定されている場合「Hello, ○○○」とレスポンスを返す
クエリ文字列が指定されていない場合「Hello, Node.js」とレスポンスを返す

また、「name=○○○&name=□□□」のように、nameを複数回指定された場合は、「Hello, ○○○, □□□」のように、値をコンマで区切って出力することにします。

修正後のプログラムは以下の通りです。

var http = require('http');
var url = require('url');

var server = http.createServer(listener);
server.listen(8080);
console.log('Server start');

function listener(request, response) {
  var urlInfo = url.parse(request.url, true);
  var pathname = urlInfo.pathname;
  if (pathname == '/') {
    response.statusCode = 200;
    response.setHeader('Content-type', 'text/plain');
    response.write('Document root');
    response.end();
  }
  else if (pathname == '/hello') {
    var name = urlInfo.query.name;
    if (!name) {
      name = 'Node.js';
    }
    if (typeof name == 'object') {
      name = name.join(', ');
    }
    response.statusCode = 200;
    response.setHeader('Content-type', 'text/plain');
    response.write('Hello, ' + escape(name));
    response.end();
  }
  else {
    response.statusCode = 404;
    response.setHeader('Content-type', 'text/plain');
    response.write('Not found');
    response.end();
  }
}

function escape(str) {
  str.replace(/&(?!\w+;)/g, '&')
  str.replace(/</g, '&lt;')
  str.replace(/>/g, '&gt;')
  str.replace(/"/g, '&quot;');
  return str;
}

昨日のプログラムに追加した内容は、以下の通りです。

9行目

parseメソッドの2つ目のパラメータにtrueを渡して、クエリ文字列をパースします。

18行目

パースされたクエリ文字列のうち、「name=○○○」の部分を変数nameに代入します。

19~21行目

「name=○○○」のクエリ文字列が指定されていない場合は、変数nameに「Node.js」を代入します。

22~24行目

「name=○○○&name=□□□」のようにnameを複数回指定された場合、パース後の結果が配列になります。
その場合は、配列の個々の値をカンマ区切りで連結して、変数nameに代入しなおします。

27行目

「Hello, ○○○」(「○○○」は変数nameの値)のレスポンスを返します。

38~44行目

文字列中の「&」「<」「>」「"」を、それぞれ「&amp;」「&lt;」「&gt;」「&quot;」に変換する関数です。