この間は 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