JavaScript
Node.js
jQuery

node.js 超入門③簡単なwebアプリケーションを作ってみる

ついに第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);

こんな感じになります。
実際に使ってみるとこんな感じになります。

スクリーンショット 2017-09-10 12.13.12.png

今回は、フォームから受け取った値を出せるようになったので、次回以降はこのデータを永続化させるためにDBも使ってみようかと思います。