複数ページのルーティングとフォームの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(){
var post = qs.parse(body);
……略……endイベントハンドラで最初に行なっているのは、先ほどdataイベントで受け取ったデータをまとめてある変数bodyをパースする処理です。これは、querystringオブジェクトの「parse」というメソッドで行なっています。このメソッドは、引数に渡されたクエリー文字列をパースし、オブジェクトにまとめます。例えば、こんな具合です。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();
}
}
}
※関連コンテンツ