node.jsのロゴ

Node.jsについて

Node.jsはJavascriptで構築できるサーバーサイド環境のことです。

近年、AWSなど、クラウドのサーバー環境が充実してきたことにより、サーバーレスなシステム(厳密にはサーバーは構築されています)が人気です。

その筆頭とされているのがNode.jsで、RubyやPHPなどのいわゆるサーバーサイド言語を使わなくても、Javascriptだけでサーバー構築を行うことができます。

Node.jsについての詳しい解説や、開発環境の構築方法については、以下の記事を参考にしてください。

※この記事では、簡易なWebサイトの開発を通して、Node.jsの使い方を学んでいきます。Javascriptの知識がある方を対象に書いていますので、予めご了承ください。

Node.jsの使い方

Hello World!を出力

それでは早速、Hello World!をブラウザに表示させてみましょう。

hello.jsというファイルを作り、以下のコードを記述します。

var http = require('http');

var server = http.createServer(function(req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.write('Hello World!');
  res.end();
});

server.listen(1234);
console.log('サーバーを起動しました');

ファイルが作成できたら、nodeコマンドを使って、このWebサーバーを起動しましょう。

node hello.js
サーバーを起動しました

コンソールに「サーバーを起動しました」が出力されたら、ブラウザでhttp://localhost:1234にアクセスします。(サーバーを停止する場合は、Ctrl + c を実行)

できましたね。非常にプレーンなものですが、驚くほど簡単にWebサーバーが作れることがわかります。

HTMLファイルの読み込み

先ほどの、レスポンスのwriteメソッドにHTML文を記述すれば、サイトのページをつくることができます。

しかし、それではあまりにも非効率なので、Node.jsの「fs」というオブジェクトを利用して、HTMLファイルを読み込みましょう。

カレントディレクトリにtemp.htmlとsample.jsファイルを作成してください。

temp.html

<!DOCTYPE html>
<html>
<head>
  <meta charset='utf-8'>
  <title>gt;sample</title>
</head>
<body>
  <h1>title</h1>
  <p>hogehoge</p>
</body>
</html>

sample.js

var http = require('http');
var fs = require('fs');

var server = http.createServer(function(req, res) {
  fs.readFile('./temp.html', 'utf-8', function(err, data) {
    res.writeHead(200, {'Content-Type7': 'text/html'});
    res.write(data);
    res.end();
  });
});

server.listen(1234);
console.log('サーバーを起動しました');

 

それでは、nodeコマンドでsample.jsを起動します。

HTMLファイル(temp.html)を読み込んでいますね!

ページ遷移の実装

Node.jsのページ遷移は、通常のWeb開発での考え方と少し異なります。

Node.jsでは、リクエスト(req.url)ごとにレスポンスとして返却する内容を使い分けることで、結果的にページ遷移を実現します。

実際にコードを書きながらみていきましょう。カレントディレクトリに、index.html,next.html,sample.jsの3つのファイルを作成します。

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset='utf-8'>
  <title>index</title>
</head>
<body>
  <h1>最初のページ</h1>
  <p>ここは最初のページです</p>
  <a href="/next">次のページへ</a>
</body>
</html>

next.html

<!DOCTYPE html>
<html>
<head>
  <meta charset='utf-8'>
  <title>next</title>
</head>
<body>
  <h1>次のページ</h1>
  <p>ここは次のページです</p>
  <a href="/index">最初のページへ</a>
</body>
</html>

sample.js

var http = require('http');
var fs = require('fs');

var server = http.createServer(function(req, res) {
  var target = '';
  switch (req.url) { 
    case '/':
      target = './index.html';
      break;
    case '/index':
      target = './index.html';
      break;
    case '/next':
      target = './next.html';
      break;
    default:
      res.writeHead(404, {'Content-Type': 'text/plain'});

      res.end('bad request');
      return;
  }

  fs.readFile(target, 'utf-8', function(err, data) {
    res.writeHead(200, {'Content-Type7': 'text/html'});
    res.write(data);
    res.end();
  });
});

server.listen(1234);
console.log('サーバーを起動しました');

nodeコマンドでsample.jsを起動します。

ページ遷移ができました!

httpリクエストオブジェクトのURLプロパティ(req.url)を使い、リクエストされたURL毎に処理を分岐させています。

上記のURLのどれにも当てはまらない場合、writeHeadメソッドでステータスコードを404に設定し、bad requestというテキストを表示させます。

ここではNode.jsの仕組みを理解するためにこのような書き方をしましたが、これらの分岐はフレームワークを使って実装するのが一般的です。

送信データの処理

フォームから送信されたデータの処理は、Webアプリの基本的なシステムです。

ここでは、ユーザーが送信したデータを取得していきたいと思います。

Node.jsでは、フォームから送信されたデータは、リクエスト時のコールバック関数が受け取るhttpリクエストオブジェクトにすべて格納されています。

それでは、index.htmlとsample.jsの2つのファイルを作成して実装していきましょう。

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset='utf-8'>
  <title>index</title>
</head>
<body>
  <a href="/?name=hoge&age=20">GET</a>
  <form action="/" method="post">
    <button type="submit">POST</button>
    <input type="text" name="name" value="fuga">
    <input type="text" name="age" value="30">
  </form>
</body>
</html>

sample.js

var http = require('http');
var fs = require('fs');
var url = require('url'); //URLを解析
var qs   = require('querystring'); //クエリ文字を扱う

var indexPage = fs.readFileSync('./index.html', 'utf-8');

var server = http.createServer(function(req, res) {
  //フォームリクエストがGETかPOSTかを確認
  if(req.method == 'GET') {
    //parseメソッドを用いて、リクエストのあったURLを解析
    //第二引数をtrueにすることで、解析結果をオブジェクト型で受け取る
    var urlParts = url.parse(req.url, true);
    console.log('---GET Request---');
    console.log(urlParts);
    console.log('nameは' + urlParts.query.name);
    console.log('ageは' + urlParts.query.age);
  } else {
    var body = '';
    //dataイベントを登録,POSTリクエストで呼び出される
    req.on('data', function(data) {
      body += data; //受けとったデータを連結
    });
    //データの受信が完了次第endイベントを発生させる
    req.on('end',function() {
      //連結した受信データを、parseメソッドで解析
      var params = qs.parse(body);
      console.log('---POST Request---');
      //解析したデータはオブジェクト型なので、nameやageでアクセスできる
      console.log('nameは' + params.name);
      console.log('ageは' + params.age);
    });
  }

  res.writeHead(200, {'Content-Type7': 'text/html'});
  res.write(indexPage);
  res.end();
});

server.listen(1234);
console.log('サーバーを起動しました');

例のごとくnodeコマンドでsample.jsを起動します。

ブラウザからGETリクエスト、POSTリクエストをそれぞれ送信した結果が↓です。

$ node sample.js 
サーバーを起動しました
---GET Request---
nameはhoge
ageは20
---POST Request---
nameはfuga
ageは30

ちなみに、URLの解析結果(url.parse(req.url, true);)がこちらです。

Url {
  protocol: null,
  slashes: null,
  auth: null,
  host: null,
  port: null,
  hostname: null,
  hash: null,
  search: '?name=hoge&age=20',
  query: { name: 'hoge', age: '20' },
  pathname: '/',
  path: '/?name=hoge&age=20',
  href: '/?name=hoge&age=20' }

queryの値がオブジェクト型になっていますね。このおかげで「urlParts.query.name」でアクセスすることができます。

(オブジェクト型とは、名前をキーにしてアクセスできる配列のことです。他の言語では連想配列やハッシュなどと呼ばれます。)

このように、GETとPOSTの処理はかなり違います。特にPOSTの場合は、イベントハンドラを登録しなければならないので、少し手間がかかります。

しかし、ページ遷移の時と同じく、これらの処理もフレームワークを使って行うことが一般的です。

画像の読み込み

Node.jsでは、「Stream」という機能を使うと、cssやjavascript、画像ファイルの供給を行うことができます。

Streamの機能を使い、画像ファイルを供給させ、ファイルサーバーとして動作させていきましょう。

var http = require('http');
var url = require('url');
var fs = require('fs');

var server = http.createServer(function(req, res) {
  var urlParts = url.parse(req.url);
  //現在実行中のディレクトリパス + / + 入力されたURLパス
  var path = __dirname + '/' + urlParts.pathname;
  //ファイルを読み込むためのストリームオブジェクトを生成
  var stream = fs.createReadStream(path);
  //読み込んだデータを引数で指定したデータにそのまま流し込む
  stream.pipe(res);
});

server.listen(1234);
console.log('サーバを起動しました');

同ディレクトリ内に画像ファイルを用意して、URLにアクセスしてみましょう。

ここでは、node_js.jpgというファイルを用意して、http://localhost/node_js:1234.jpgでアクセスします。

画像を表示できました!

モジュールの作成

Node.jsでコードを再利用するには、「モジュール」を使います。

ここでは、最小限のプログラムでモジュールを実装していきます。

func.js、sample.jsというファイルを作成し、以下のコードを記述してください。

func.js

exports.add = function(val1, val2) {
  return val1 + val2;
}

exports.sub = function(val1, val2) {
  return val1 - val2;
}

sample.js

var func = require('./func');
console.log(func.add(1, 2));
console.log(func.sub(10, 3));

実行結果

$ node sample.js 
3
7

sample.jsからfunc.jsの関数を呼び出すことができましたね。

この「exports-require」の仕様により、グローバルスコープの汚染を気にせずに開発を進められます。

続編はこちら