この間は Rails をやろう、みたいな事を書いたくせに、ふと気になって JavaScript の本を読んでいる。目的は jQuery なんだけど Node.js が面白そうだったのでさわってみることにした。
まずはダウンロードとインストールから。nodejs.orgにアクセスすると、ページの真ん中に INSTALL ボタンがあるので、クリックしてインストーラをダウンロード。バージョンは v0.10.29。ダウンロードされた node-0.10.29-x64.msi をダブルクリックしてインストールする。特に迷うこともなくインストールは終了。
試しにバージョンを表示してみる。
^o^ > node -v v0.10.29
うまくインストールできてるようだ。
さて、Node.js には npm というパッケージマネージャが付属している。これでパッケージの管理ができるんだけど、プロジェクトを作るときにも使うらしい。
とりあえずは、単純にリクエストされたファイル(画像)を返すだけのサーバを作ってみることにした。
まずは、プロジェクトのフォルダを作ってその中に移動し、npm init で初期化する。
^o^ > mkdir image_server
^o^ > cd image_server
^o^ > npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sane defaults.
See `npm help json` for definitive documentation on these fields
and exactly what they do.
Use `npm install --save` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
name: (image_server)
version: (0.0.0) 0.0.1
description:
entry point: (index.js) server.js
test command:
git repository:
keywords:
author: takatoh
license: (ISC)
About to write to C:\Users\hiro\Documents\w\image_server\package.json:
{
"name": "image_server",
"version": "0.0.1",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "takatoh",
"license": "ISC"
}
Is this ok? (yes) yes
いくつか質問に答えると、プロジェクトの雛形が完成。この時点でフォルダの構成はこうなっている。
^o^ > tree /F
フォルダー パスの一覧: ボリューム OS
ボリューム シリアル番号は FE2A-F7C6 です
C:.
package.json
サブフォルダーは存在しません
package.json というファイルがあるだけだね。
次は依存するパッケージのインストール。今回はリクエストに応じて送信するファイルの MIME TYPE を調べるために、mime というパッケージを利用する。これを package.json に追加する。
{
"name": "image_server",
"version": "0.0.1",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"mime": "*"
},
"author": "takatoh",
"license": "ISC"
}
色をつけたところが追記したところ。"*" は最新のバージョンをインストールすることを示している。ここに特定のバージョンを書けばバージョン指定もできるようだ。
追記が終わったら mime パッケージのインストール。npm install コマンドを使う。
^o^ > npm install npm WARN package.json [email protected] No description npm WARN package.json [email protected] No repository field. npm WARN package.json [email protected] No README data [email protected] node_modules\mime
npm install は package.json を参照して、まだインストールされていないパッケージをインストールしてくれる。パッケージはプロジェクトフォルダの中の node_modules フォルダにインストールされる。この時点でフォルダ構成はこうなっている。
^o^ > tree /F
フォルダー パスの一覧: ボリューム OS
ボリューム シリアル番号は FE2A-F7C6 です
C:.
│ package.json
│
└─node_modules
└─mime
│ LICENSE
│ mime.js
│ package.json
│ README.md
│ test.js
│
└─types
mime.types
node.types
node_modules の下に mime がインストールされているのがわかる。
さあ、今度はサーバ本体だ。いろいろ調べながら出来上がったのがこれ。
var http = require("http");
var fs = require("fs");
var url = require("url");
var mime = require("mime");
server = http.createServer(function(request, response) {
var path = url.parse(request.url).pathname;
console.log(path);
var mimetype = mime.lookup(path);
var filepath = "./images" + path;
fs.readFile(filepath, function (err, data) {
if (err) {
response.writeHead(404, {"Content-Type" : "text/plain"});
response.write("File not found.");
response.end();
} else {
response.writeHead(200, {"Content-Type" : mimetype});
response.write(data);
response.end();
}
});
});
console.log("Start server on port 8888.");
server.listen(8888);
require 関数でパッケージを読み込んで変数に代入している。mime 以外は Node.js に付属しているパッケージで、http はその名のとおり HTTP サーバ/クライアント。fs はローカルのファイルシステムにアクセスするため、url はリクエストの URL を解析するために読み込んでいる。
HTTP サーバは、http.createServer で作れる。引数にはリクエストに応答する関数を指定している。この関数には request と response のオブジェクトが引数として渡されるので、request を解析して response に書き込めばいい。今回は、要求されたファイルを ./images 以下から読み込んで送信している。もしエラーが発生したら、404 File not found を返している。
それじゃ、images フォルダにサンプルの画像を配置しよう。
^o^ > tree /F images
フォルダー パスの一覧: ボリューム OS
ボリューム シリアル番号は FE2A-F7C6 です
C:\USERS\TAKATOH\DOCUMENTS\W\IMAGE_SERVER\IMAGES
│ Penguins.jpg
│
└─data
Desert.jpg
これで準備は完了。サーバを起動しよう。次のようにする。
^o^ > node server.js Start server on port 8888.
これでポート 8888 で待ち受けている状態になった。ブラウザからアクセスしてみよう。
うまくいった!
参考にしたページ:
cf. http://nodejs.jp/nodejs.org_ja/docs/v0.4/api/http.html#request.url
cf. http://nodejs.jp/nodejs.org_ja/docs/v0.4/api/fs.html#fs.readFile
cf. http://stackoverflow.com/questions/5316324/automatic-mimetypes-in-javascript-node-js
