複数ページのルーティングとフォームのPOST送信 (4/4)
作成:2013-04-27 08:47
更新: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」というオブジェクトをロードして使っています。冒頭付近にある以下の文ですね。
ここでは、request.methodでGET時とPOST時の処理を分けています。GET時の処理は先ほどと同じですね。問題はPOST時の処理です。ここでは、まず「data」というイベントハンドリングを行なっています。
そして、すべての受信処理が完了した後で、POSTデータの処理とページのレンダリングなどを行います。これは「end」というイベントハンドラを用意して実装します。
POST送信は、データの受信がちょっと面倒ですが、それさえクリアできれば後は簡単です。これでだいぶ普通のWebページのようなものが作れるようになってきましたね。(まぁ、Node.jsで普通のWebサーバーのような使い方をするのがよいか?という問題はありますが……)
スクリプトを記述したら、実際に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='';このdataイベントは、POSTで送信されたデータを受信した際に発生します。イベントハンドラでは、送られてきたデータが引数として渡されます。こうして得られたデータを変数bodyにどんどん追加していくくことで、受信したデータが完成されていきます。
request.on('data', function (data) {
body +=data;
});
そして、すべての受信処理が完了した後で、POSTデータの処理とページのレンダリングなどを行います。これは「end」というイベントハンドラを用意して実装します。
request.on('end',function(){endイベントハンドラで最初に行なっているのは、先ほどdataイベントで受け取ったデータをまとめてある変数bodyをパースする処理です。これは、querystringオブジェクトの「parse」というメソッドで行なっています。このメソッドは、引数に渡されたクエリー文字列をパースし、オブジェクトにまとめます。例えば、こんな具合です。
var post = qs.parse(body);
……略……
a=abc&x=xyz↓
{ a: "abc", x:"xyz" }この際、URLエンコードされた値なども自動的に元の文字列に復号されます。こうして得られた変数postから、必要に応じて値を取り出せばいいわけです。今回はcontent3をレンダリングするとき以下のようにしていますね。
content: ejs.render(送信された値は、post.idname、post.passで取り出せます。後は、それらをまとめてレンダリングするだけです。
routes[url_parts.pathname].content,
{
idname: post.idname,
pass: post.pass
}
)
POST送信は、データの受信がちょっと面倒ですが、それさえクリアできれば後は簡単です。これでだいぶ普通のWebページのようなものが作れるようになってきましたね。(まぁ、Node.jsで普通のWebサーバーのような使い方をするのがよいか?という問題はありますが……)
(by. SYODA-Tuyano.)
※プログラムリストが表示されない場合
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(); } } }
※関連コンテンツ