Bluemix上でExpressを利用してWebページを表示させる練習をした。Expressの説明サイトではトップページを表示させることだけに言及しているが、ここではトップページだけでなく、配下のページ(例えば 「http://hoge.com/page1」)のように、ドメイン名の下に「ファイル名」を指定した形式で特定のページ表示させる方法についても記載する。
また、入力(POST)についても記載する。
なお、マークアップ言語は、なんか流行なのでjadeを使用している。
なんでExpressを使うかと言うと、BluemixでランタイムをNode.jsでWebアプリケーションを作成するとExpressを使用したサンプルコードが用意されるため。
サンプルコードに使われているんだから、それを使えるようにしておいたほうが有利といえば有利なんだろうな。
ソースの全体
ソースを細かく分けて解説するので、まず全体像を示す。
BluemixのダッシュボードよりCloud Foundry アプリ/アプリの作成 -> Webアプリ -> SDK for Node.js で作成したアプリのコードを元に追加、削除しているので、つぎはぎ感があるが我慢して。
/*eslint-env node*/
//Expressで、ドメイン配下をかえて、ページを切り替える練習
//------------------------------------------------------------------------------
// node.js starter application for Bluemix
//------------------------------------------------------------------------------
// This application uses express as its web server
// for more info, see: http://expressjs.com
var express = require('express');
// cfenv provides access to your Cloud Foundry environment
// for more info, see: https://www.npmjs.com/package/cfenv
var cfenv = require('cfenv');
// create a new express server
var app = express();
// jageの利用
app.set('view engine', 'jade');
//jadeを格納するディレクトリの設定。これでアプリケーション直下のviewsフォルダ配下を指定している。
app.set('views', __dirname + '/views');
//Postを扱う時必要なBodyPerserの利用宣言
var bodyParser = require('body-parser');
app.use(bodyParser());
// https://hoge.com/xxx <- このxxxの所を変えると、それぞれのページが表示できるようにする。
// xxx が / ※すなわちトップページ。
app.get('/', function (req, res) {
res.send('Hello Root');
});
// xxx が page1 なら 以下のページを表示
app.get('/page1', function (req, res) {
res.send('Hello page1');
});
app.get('/page2', function (req, res) {
// views/index.jadeをレンダー jadeをレンダーするならjadeモジュールが必要
res.render('index', { title: 'Express' });
});
//POSTの場合、最初はgetリクエストが来るみたいなので、getリクエスト用の処理が必要
app.get('/form1', function(req, res) {
console.log(req.body);
res.render('form1', { title: 'Express Sample Posted ver 0.0.1'});
});
//こちらはPOSTを受信したとき。
//POSTを受信したときに違うjadeファイルをレンダー出来る。もちろんgetと同じファイルを指定しても良い。
//さらに、POStされた値で分岐。表示するjadeファイルを変えることもできる。
//なお、サブミットの時、別のブラウザータブを開かせたくない場合、jadeファイルのFORMタグの target="_self" とする。
app.post('/form1', function(req, res) {
console.log(req.body);
if (req.body.word == "test") {
res.render('form3', { title: 'Express Sample Posted ver 0.0.1', word: req.body.word});
} else {
res.render('form2', { title: 'Express Sample Posted ver 0.0.1', word: req.body.word});
}
});
// ポートはどうやらBluemix君にお任せなので、以下のおまじないでリッスン開始。
// get the app environment from Cloud Foundry
var appEnv = cfenv.getAppEnv();
// start server on the specified port and binding host
app.listen(appEnv.port, function() {
// print a message when the server starts listening
console.log("server starting on " + appEnv.url);
});
form(method="POST", target="_self")
input(type="text", name="word" value="")
input(type="hidden", name="mode" value="input")
input(type="submit", value="送信")
p #{word}
p テスト成功!!
p #{word}
"dependencies": {
"express": "4.12.x",
"cfenv": "1.0.x",
"jade": "1.1.4",
"body-parser": "1.13.x"
},
準備
まずは、jadeとBodyPerserの利用準備。
// jageの利用
app.set('view engine', 'jade');
//jadeを格納するディレクトリの設定。アプリケーション直下のviewsフォルダ配下を指定している。
app.set('views', __dirname + '/views');
//Postを扱う時必要なBodyPerserの利用宣言
var bodyParser = require('body-parser');
app.use(bodyParser());
以下で、jadeで記述されたWebページを表示できるようになる。
app.set('view engine', 'jade');
jadeファイルを格納するフォルダを指定するコードが以下。
アプリケーション直下のviewsフォルダの配下にjadeファイルを格納してあるよと宣言している。
app.set('views', __dirname + '/views');
POSTを利用する宣言は、上のコードを見て欲しい。
Jadeモジュールと、body-perserは、Bluemixではpackage.jsonで以下のように宣言しておくとデプロイ時に勝手にインストールしてくれる。
"jade": "1.1.4",
"body-parser": "1.13.x"
サンプルのjadeファイルは、さっき宣言したとおりviewsフォルダの配下に格納しておく。こんな感じで。
WebページをWebサーバーに書かせる
Webページを書かせる基本形のコードは以下のとおり。
1行目で、そのURLの「/」(トップページ)にアクセスした場合、というように「場所」を指定する。(専門用語ではこの「場所」のことを「ルート」というらしい。)
二行目では、HTMLやjadeを使うことなく単純に「Hello Root」とWebページに表示するように指定している。
app.get('/', function (req, res) {
res.send('Hello Root');
});
上の例は、「/」(トップページ)にアクセスした場合である。Expreesに触れたサイトだと大体ここまでしか説明がない。もう少し踏み込んで今度は、例えば「http://xxx.jp/page1」のようにURL配下の「page1」というところにアクセスした場合を指定してみよう。
以下の1行目のように「ルート」に「/page1」を指定すればよいらしい。
app.get('/page1', function (req, res) {
res.send('Hello page1');
});
サーバーを実行して、ページにアクセスすると以下のようになる。
formタグとPOSTを使う
Webページで入力をさせるformタグを使う場合は、3つコツがあるらしい。
1. app.getでformタグを含むページを初回に描画する。(ようにコードを書く)
2. app.postで入力値が入ってきた時(POSTリクエストを受信した時)の処理をする。
3. body-parserモジュールを使う。
app.getでの初回描画
まず、http:xxx.jp/form1にアクセスしたときにページを初回描画するコードを書く。
なおform1は、準備の項で述べたとおり、/views配下に格納したform1.jadeというファイルが使用される。
app.get('/form1', function(req, res) {
res.render('form1', { title: 'Express Sample Posted ver 0.0.1'});
});
サーバーを実行して、ページにアクセスすると以下のようになる。
app.postでの処理
http:xxx.jp/form1で値が入力され、POSTリクエストが来たときのための処理コードが以下。
入力された値は、「req.body.formタグのnameで指定した名前」に(form1.jadeだと「word」と指定)格納されている。
この値を条件文にかまして、処理を分岐させることも出来る。
以下では、入力された値が「test」という文字列なら、form3.jadeを描画するようにしている。「test」以外ならform2.jadeを描画するようになっているが、form2.jadeは自分で作って欲しい。
app.post('/form1', function(req, res) {
if (req.body.word == "test") {
res.render('form3', { title: 'Express Sample Posted ver 0.0.1', word: req.body.word});
} else {
res.render('form2', { title: 'Express Sample Posted ver 0.0.1', word: req.body.word});
}
});
body-parserモジュールの使用
POSTリクエストを処理するために、body-parserモジュールを使わないと処理がされない。Bluemixのモジュールのインストールについては準備の項を見て欲しい。