libro
www.tuyano.com
初心者のための Node.jsプログラミング入門

複数ページのルーティングとフォームのPOST送信 (4/4)

作成:2013-04-27 08:47
更新:2013-04-27 08:47

■POST送信されたデータの処理

続いて、Node.jsのスクリプトを作成しましょう。今回は、フォームの送信先でcontent3.ejsを表示するため、"/post"というパスの情報を追加してあります。

スクリプトを記述したら、実際にNode.jsを起動し、アクセスしてみましょう。http://127.0.0.1:1234/にアクセスすると用意されたフォームが表示されます。ここでIDとPASSに適当に値を記入し送信すると、送信された内容が表示されます。

今回のスクリプトでは、「querystring」というオブジェクトをロードして使っています。冒頭付近にある以下の文ですね。
var qs = require('querystring');
このquerystringは、クエリー文字列を扱うための機能を提供します。これを利用することで、クエリー文字列から必要な値を適格に取り出せるようになるわけです。――では、スクリプトの内容を見ていきましょう。

ここでは、request.methodでGET時とPOST時の処理を分けています。GET時の処理は先ほどと同じですね。問題はPOST時の処理です。ここでは、まず「data」というイベントハンドリングを行なっています。
var body='';
request.on('data', function (data) {
    body +=data;
});
このdataイベントは、POSTで送信されたデータを受信した際に発生します。イベントハンドラでは、送られてきたデータが引数として渡されます。こうして得られたデータを変数bodyにどんどん追加していくくことで、受信したデータが完成されていきます。

そして、すべての受信処理が完了した後で、POSTデータの処理とページのレンダリングなどを行います。これは「end」というイベントハンドラを用意して実装します。
request.on('end',function(){
    var post =  qs.parse(body);
    ……略……
endイベントハンドラで最初に行なっているのは、先ほどdataイベントで受け取ったデータをまとめてある変数bodyをパースする処理です。これは、querystringオブジェクトの「parse」というメソッドで行なっています。このメソッドは、引数に渡されたクエリー文字列をパースし、オブジェクトにまとめます。例えば、こんな具合です。
a=abc&x=xyz
 ↓
{ a: "abc", x:"xyz" }
この際、URLエンコードされた値なども自動的に元の文字列に復号されます。こうして得られた変数postから、必要に応じて値を取り出せばいいわけです。今回はcontent3をレンダリングするとき以下のようにしていますね。
content: ejs.render(
    routes[url_parts.pathname].content,
    {
        idname: post.idname,
        pass: post.pass
    }
)
送信された値は、post.idnamepost.passで取り出せます。後は、それらをまとめてレンダリングするだけです。

POST送信は、データの受信がちょっと面倒ですが、それさえクリアできれば後は簡単です。これでだいぶ普通のWebページのようなものが作れるようになってきましたね。(まぁ、Node.jsで普通のWebサーバーのような使い方をするのがよいか?という問題はありますが……)

※プログラムリストが表示されない場合

AddBlockなどの広告ブロックツールがONになっていると、プログラムリスト等が表示されない場合があります。これらのツールをOFFにしてみてください。

●プログラム・リスト●

var http = require('http');
var fs = require('fs');
var ejs = require('ejs');
var url = require('url');
var qs = require('querystring');

var template = fs.readFileSync('./template.ejs', 'utf8');
var content1 = fs.readFileSync('./content1.ejs', 'utf8');
var content2 = fs.readFileSync('./content2.ejs', 'utf8');
var content3 = fs.readFileSync('./content3.ejs', 'utf8');

var routes = {
    "/":{
        "title":"Main Page",
        "message":"これはサンプルのページですよ。",
        "content":content1},
    "/index":{
        "title":"Main Page",
        "message":"これはサンプルのページですよ。",
        "content":content1},
    "/other":{
        "title":"Other Page",
        "message":"別のページを表示していますよ。",
        "content":content2},
    "/post":{
        "title":"Post Page",
        "content":content3}
};

var server = http.createServer();
server.on('request', doRequest);
server.listen(1234);
console.log('Server running!');

// リクエストの処理
function doRequest(request, response) {
    var url_parts = url.parse(request.url);
    // route check
    if (routes[url_parts.pathname] == null){
        response.writeHead(200, { 'Content-Type': 'text/html' });
        response.end("<html><body><h1>NOT FOUND PAGE:" + 
            request.url + "</h1></body></html>");
        return;
    }
    // get
    if (request.method == "GET"){
        var content = ejs.render( template,
            {
                title: routes[url_parts.pathname].title,
                content: ejs.render(
                    routes[url_parts.pathname].content,
                    {
                        message: routes[url_parts.pathname].message
                    }
                )
            }
        );
        response.writeHead(200, {'Content-Type': 'text/html'});
        response.write(content);
        response.end();
        return;
    }
    // post
    if (request.method == "POST"){
        if (url_parts.pathname == "/post"){
            var body='';
            request.on('data', function (data) {
                body +=data;
            });
            request.on('end',function(){
                var post =  qs.parse(body);
                var content = ejs.render( template,
                    {
                        title: routes[url_parts.pathname].title,
                        content: ejs.render(
                            routes[url_parts.pathname].content,
                            {
                                idname: post.idname,
                                pass: post.pass
                            }
                        )
                    }
                );
                response.writeHead(200, {'Content-Type': 'text/html'});
                response.write(content);
                response.end();
            });
        } else {
            response.writeHead(200, {'Content-Type': 'text/plain'});
            response.write("NO-POST!!");
            response.end();
        }
    }
}

※関連コンテンツ

「初心者のための Node.jsプログラミング入門」に戻る