ついに第3回です。
第一弾ではnode.jsの超基礎を学びながら簡単なwebサーバを作りました。
第二弾では、他のファイルに分割する方法や、ルーティングやファイルシステムを使ってHTMLで表示等を行いました。
じゃあ今回は、これらを使いつつ、簡単なwebアプリケーションをnode.jsで作ってみようと思います。
[基礎編]npmとは
- node package manager
- PHPで言うcomposerのようなもの
- グローバルインストール
npm install -g [パッケージ名]
- ローカルインストール
npm install [パッケージ名]
テンプレートエンジンを使ってみる
素のHTMLファイルだと、サーバ側から動的に値を渡すなどが出来ません。
そこで登場するのがテンプレートエンジンです。
PHPだとTwigやSmartyが有名ですね。
今回はejs
を使っみます。
$ npm install ejs
実際にejsテンプレートを使うにはこんな感じにしてあげます。
// nodeのコアモジュールのhttpを使う
var http = require('http');
var ejs = require('ejs');
var fs = require('fs');
var config = require('./config');
var server = http.createServer();
// テンプレートを使うときはreadFileSyncを使う
var template = fs.readFileSync(__dirname + '/hello.ejs', 'utf-8');
var msg;
var n = 0;
server.on('request', function(req, res) {
// リクエストがきたらnを増やす
n++;
var data = ejs.render(template, {
title: 'こんにちわ',
content: "<b>世界</b>",
n: n
});
// 表示させるのはtextじゃなくて、htmlなので、text/htmlにする
res.writeHead(200, {'Content-Type' : 'text/html'});
res.write(data);
res.end();
});
// サーバを待ち受け状態にする
// 第1引数: ポート番号
// 第2引数: IPアドレス
server.listen(config.port);
console.log('ポート番号: ' + config.port);
ポイント
- テンプレートを使うときは、
fs.readFileSync
を使う - ejsのrenderする時の第二引数に、渡したい変数を渡してあげる
※ [注意] npmでカレントディレクトリにインストールされない場合
npm install
をした時に、なぜかカレントディレクトリにnode_modules
ができずに、
親ディレクトリのnode_modules
にインストールされる場合があります。
詳しくはこちらのリンクが非常に参考になりましたので見てみて下さい。
因みに、カレントディレクトリでnpm init
しておけば、この現象を防ぐ事が可能です。
formからデータを受け取る
まずはformを受け取れるようにejsの方を修正しておきましょう。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>簡易掲示板</title>
</head>
<body>
<form action="/" method="post">
<input type="text" name="user_name">
<input type="submit" value="投稿">
</form>
<%# 実際に投稿された内容を表示 %>
<ul>
<% for (var i = 0; i < posts.length; i++) { %>
<li><%= posts[i] %></li>
<% } %>
</ul>
</body>
</html>
次に、このフォームから受け取ったデータをテンプレートに渡して表示出来るようにします。
// nodeのコアモジュールのhttpを使う
var http = require('http');
var ejs = require('ejs');
var qs = require('querystring');
var fs = require('fs');
var config = require('./config');
var server = http.createServer();
var posts = [];
// フォームを表示する
function renderForm(posts, res) {
var data = ejs.render(template, {
posts: posts
});
res.writeHead(200, {'Content-Type' : 'text/html'});
res.write(data);
res.end();
}
// テンプレートを使うときはreadFileSyncを使う
var template = fs.readFileSync(__dirname + '/hello.ejs', 'utf-8');
server.on('request', function(req, res) {
if (req.method === 'POST') {
req.data = "";
// フォームからのデータを受信
req.on("readable", function() {
// read()はnullが来る場合もあるので空文字にする
req.data += req.read() || '';
console.log(req.data);
});
req.on("end", function() {
// パースすると、formから入力された値をquery.nameのように使えるようになる
var query = qs.parse(req.data);
console.log(query);
posts.push(query.user_name);
renderForm(posts, res);
});
} else {
renderForm(posts, res);
}
});
// サーバを待ち受け状態にする
// 第1引数: ポート番号
// 第2引数: IPアドレス
server.listen(config.port);
こんな感じになります。
実際に使ってみるとこんな感じになります。
今回は、フォームから受け取った値を出せるようになったので、次回以降はこのデータを永続化させるためにDBも使ってみようかと思います。