<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>さくらたんどっとびーず &#187; express</title>
	<atom:link href="http://sakuratan.biz/archives/tag/express/feed" rel="self" type="application/rss+xml" />
	<link>http://sakuratan.biz</link>
	<description>モロモロ工事中です</description>
	<lastBuildDate>Sun, 25 Jun 2023 12:51:51 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>node.jsとMySQLで割と普通のデータベースウェブアプリを作ってみるチュートリアル</title>
		<link>http://sakuratan.biz/archives/3101</link>
		<comments>http://sakuratan.biz/archives/3101#comments</comments>
		<pubDate>Sun, 16 Jan 2011 15:52:14 +0000</pubDate>
		<dc:creator>さくら</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[ejs]]></category>
		<category><![CDATA[express]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://sakuratan.biz/?p=3101</guid>
		<description><![CDATA[2011年はサーバサイド JavaScript の年！ サーバサイド JavaScript の本命は node.js！ ということで割と普通のウェブアプリケーションを node.js で作るためのチュートリアルを書いてみました。WebSocket とか新しめの話題は結構見ますが、PHP とかで普通のウェブアプリ作ってる人向けのチュートリアルとかあんま見ないような気がしたので、って感じです。 チュー... <div style="margin-top:1ex"><a href="http://sakuratan.biz/archives/3101">(続きを読む)</a></div>]]></description>
			<content:encoded><![CDATA[<p>2011年はサーバサイド JavaScript の年！<br />
サーバサイド JavaScript の本命は node.js！</p>
<p><a href="http://nodejs.org/"><img src="http://sakuratan.biz/blog/wp-content/uploads/2011/01/logo.png" alt="node.js" title="node.js" width="420" height="111" class="aligncenter size-full wp-image-3315" style="background-color:#22252A"/></a></p>
<p>ということで割と普通のウェブアプリケーションを node.js で作るためのチュートリアルを書いてみました。WebSocket とか新しめの話題は結構見ますが、PHP とかで普通のウェブアプリ作ってる人向けのチュートリアルとかあんま見ないような気がしたので、って感じです。</p>
<p>チュートリアルの内容ですが、コード量が少なめで機能的にも分かりやすそうなモノということで、短縮 URL ウェブアプリケーションを作ってみることにしました。bit.ly とか t.co とか nico.ms みたいなアレです。短縮 URL のデータは MySQL に保存します。</p>
<p>結構長文になっちゃったので、先に目次置いときます。</p>
<ol>
<li>node.js のインストール</li>
<li>npm (Node Package Manager) のインストール</li>
<li>express フレームワークの簡単な使い方</li>
<li>ejs テンプレートエンジンを express フレームワークで使う方法</li>
<li>node.js 用 MySQL モジュールの使用例</li>
<li>自作モジュールの作成例</li>
</ol>
<p>チュートリアルを一通り試せば簡単なウェブアプリなら作れるようになるかもしんないので、お暇な方はどうぞ。</p>
<p>あとチュートリアルで作ったソースを固めた ZIP も置いときますので、ソース見た方がはえーって人は ZIP からどうぞ。</p>
<blockquote><p>
<a href='http://sakuratan.biz/blog/wp-content/uploads/2011/01/nodejs-urlshortener.zip'>nodejs-urlshortener.zip</a>
</p></blockquote>
<p>（2011/1/18 21:20）ちろっと正規表現が変だったようで一ヶ所直して ZIP をうpり直しました。<br />
×　/^\/([0-9A-Z]{5,}$)$/<br />
○　/^\/([0-9A-Z]{5,})$/<br />
修正前の正規表現でもちゃんと動いてるので機能的にバグってる訳ではないようですが、Typo ですし $)$ は変な感じです(*´・ω・)(・ω・｀*)ﾈｰ</p>
<h3>node.js のインストール</h3>
<p>とりあえず node.js が無ければ話が始まらないのでとっととインスコしていきます。</p>
<p>node.js のアーカイブは<a href="http://nodejs.org/">公式サイト</a>の<a href="http://nodejs.org/#download">ダウンロード</a>から配布されています。2011年1月10日時点では安定版としてバージョン 0.2.6、開発版としてバージョン 0.3.4 のアーカイブが配布されています。</p>
<p>今んところ開発中の機能が使いたい訳でも無いので安定版をインストールすることにしました。開発版を使う場合はアーカイブのソースを使うよりも、github の <a href="https://github.com/ry/node">node.js のリポジトリ</a>からソースを持ってきた方が良いと思います。</p>
<p>node.js が動く環境ですが<a href="http://nodejs.org/">公式サイト</a>によると Linux、Macintosh、Solaris でテストされているということです。また Windows/Cygwin、FreeBSD、OpenBSD でもだいたい動くとのことです。</p>
<p>さくらの VPS の CentOS と MacBook にインスコしてみたのですが、どちらもインストール作業自体はあっさり簡単に終わりました。インストールする前に必要になるライブラリとかが若干違いますので OS 別にインストール方法を説明します。</p>
<h4>CentOS の場合</h4>
<p>CentOS の場合、node.js をインストールする前に OpenSSL と Python が必要になります。Python を yum 以外の方法でインストールする場合はバージョン 2.4 以降をインストールしてください。</p>
<div class="codecolorer-container bash dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ <span style="color: #c20cb9; font-weight: bold;">yum install</span> openssl-devel<br />
$ <span style="color: #c20cb9; font-weight: bold;">yum install</span> python</div></div>
<p>OpenSSL と Python がインストールできたら <a href="http://nodejs.org/#build">ビルド方法の説明</a> に従って node.js をインストールします。make install は root で実行してください。</p>
<div class="codecolorer-container bash dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ <span style="color: #c20cb9; font-weight: bold;">tar</span> xvzf node-v0.2.6.tar.gz<br />
$ <span style="color: #7a0874; font-weight: bold;">cd</span> node-v0.2.6<br />
$ .<span style="color: #000000; font-weight: bold;">/</span>configure<br />
$ <span style="color: #c20cb9; font-weight: bold;">make</span><br />
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #c20cb9; font-weight: bold;">install</span></div></div>
<p>ビルド／インストールはすぐ終わると思います。</p>
<p>インストールが完了すると /usr/local/bin/node に node.js のバイナリがインストールされます。インストール先を変更したい場合は configure 実行時に &#8211;prefix=DIR オプションを指定してください。その他のビルド／インストールオプションについては、configure &#8211;help で参照してください。</p>
<h4>Mac OS X の場合</h4>
<p>Mac OS X の場合、コンパイルするのに GNU C コンパイラ (GCC) が必要になります。GCC は Xcode からインストールするのが良いと思います。Xcode のインストール方法は <a href="http://osksn2.hep.sci.osaka-u.ac.jp/~taku/osx/install_xcode.html">このページ</a>等を参考にしてください。（ポックンの MacBook、iPhone の SDK 入れたときに Xcode 入れちゃったので、インストール手順覚えとらんので説明できんとです。サーセン）</p>
<p>Mac OS X には Python は元からインストールされていますので Xcode 以外のインストールは不要です。</p>
<p>node.js のビルド／インストールは、CentOS の場合と同じように configure / make で行います。</p>
<div class="codecolorer-container bash dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ <span style="color: #c20cb9; font-weight: bold;">tar</span> xvzf node-v0.2.6.tar.gz<br />
$ <span style="color: #7a0874; font-weight: bold;">cd</span> node-v0.2.6<br />
$ .<span style="color: #000000; font-weight: bold;">/</span>configure<br />
$ <span style="color: #c20cb9; font-weight: bold;">make</span><br />
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #c20cb9; font-weight: bold;">install</span></div></div>
<p>node.js には Mac OS X 用パッケージを作るためのスクリプトが tools/osx-dist.sh に用意されているのですが、後述する npm と設定が一致していないため使わない方が良いと思います。</p>
<h3>npm (Node Package Manager) のインストール</h3>
<p>npm (Node Package Manager) は node.js の CPAN みたいなもので外部モジュールのインストールに使います。</p>
<p>npm のインストール用スクリプトが http://npmjs.org/install.sh にありますので、ダウンロードして実行します。</p>
<div class="codecolorer-container bash dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">$ </span>curl http:<span style="color: #000000; font-weight: bold;">//</span>npmjs.org<span style="color: #000000; font-weight: bold;">/</span>install.sh <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sh</span></div></div>
<p>ただまあこれ、そのまま一般ユーザーで動かすとディレクトリにパーミッションが無いエラーで異常終了します。</p>
<p>node.js と同じ /usr/local 以下にファイルを置こうとしてるので当然と言えば当然ですが、<a href="https://github.com/isaacs/npm/issues/issue/294">npm 自体がこの辺の仕様を固めきっていないみたい</a>ですのでアレコレ…</p>
<p>どこから説明したら良いものか悩みますが、<a href="https://github.com/isaacs/npm/blob/master/doc/developers.md#readme">npm のリポジトリには誰でもパッケージをアップロードできる</a>ので、root で npm をインストールする環境だとセキュリティホールになるようなパッケージもアップロードできたりしちゃうのですが、npm の作者さん的には誰でもパッケージメンテナになれる状態を保っておきたいので、npm 自体や npm パッケージを root 権限でインストールしない方がいいよ、ということらしいです。自分で書いてて変な日本語ww</p>
<p><a href="https://github.com/isaacs/npm">isaacs / npm</a> に root 権限なしでインストールする方法が何個か説明されてますが、ポックン的にはリスクは把握しましたし、Your own risk とか *NIX だと割と当たり前なんで sudo でインスコすることにしました。</p>
<div class="codecolorer-container bash dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">$ </span>curl http:<span style="color: #000000; font-weight: bold;">//</span>npmjs.org<span style="color: #000000; font-weight: bold;">/</span>install.sh <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">sh</span></div></div>
<p>心配な人は <a href="https://github.com/isaacs/npm">isaacs / npm</a> に従って root 権限なしでインスコするか、<a href="https://gist.github.com/579814">https://gist.github.com/579814</a> の説明に従って ~/local とかに npm をインスコするのが良いと思います。</p>
<p>なお npm を sudo でインスコした場合、npm でパッケージをインスコする際も root で実行する必要があります。root でパッケージをインスコすると npm がワーニングを出しますがとりあえず無視です。</p>
<p>あとこの辺は、もうじき仕組みが変わる予定だそうです。変わった後でこのブログ見た人は上の説明を無視してください。</p>
<blockquote><p>
It is on the roadmap to make npm do a bunch of chown/setuid stuff when sudoed, so eventually it&#8217;ll actually be safer to run as root than as a user account, but that&#8217;s a refactor that is slowly progressing.<br />
<cite><a href="https://github.com/isaacs/npm">https://github.com/isaacs/npm</a></cite>
</p></blockquote>
<h4>モジュールのインストール</h4>
<p>npm がインスコできたらモジュールをインスコしていきます。</p>
<p>今回のチュートリアルでは、<a href="https://github.com/felixge/node-mysql">node-mysql</a> (MySQL)、<a href="http://expressjs.com/">express</a> (express フレームワーク)、<a href="https://github.com/visionmedia/ejs">ejs</a> (テンプレートエンジン) を使います。</p>
<p>モジュールのインストールは npm install コマンドで行います。npm を sudo でインスコした場合は、npm install は root で実行してください。</p>
<div class="codecolorer-container bash dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ npm <span style="color: #c20cb9; font-weight: bold;">install</span> mysql<br />
$ npm <span style="color: #c20cb9; font-weight: bold;">install</span> express<br />
$ npm <span style="color: #c20cb9; font-weight: bold;">install</span> ejs</div></div>
<p>あと mysql モジュールをインストールする前に MySQL 本体をインスコしておいてください。本筋と関係無いので MySQL のインスコ方法は省略します。</p>
<h3>node.js を試してみる</h3>
<p>インストールが終わったら早速 node.js を動かしてみます。</p>
<p>最初は <a href="http://nodejs.org/">node.js 公式サイト</a>のサンプルコードを動かしてみます。このサンプルはウェブサーバを起動し、HTTP 経由のアクセスに対して Hello World を返します。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #006600; font-style: italic;">// モジュールの読み込み</span><br />
<span style="color: #003366; font-weight: bold;">var</span> http <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'http'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// サーバを起動する</span><br />
http.<span style="color: #660066;">createServer</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>req<span style="color: #339933;">,</span> res<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; res.<span style="color: #660066;">writeHead</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">200</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><span style="color: #3366CC;">'Content-Type'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'text/plain'</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; res.<span style="color: #660066;">end</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Hello World<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">listen</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">8124</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;127.0.0.1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Server running at http://127.0.0.1:8124/'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>↑のソースをコピペして適当なディレクトリに example.js として保存します。ターミナルから node コマンドを実行して node.js を起動します。</p>
<div class="codecolorer-container bash dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ node example.js<br />
Server running at http:<span style="color: #000000; font-weight: bold;">//</span>127.0.0.1:<span style="color: #000000;">8124</span></div></div>
<p>Server running &#8230; メッセージが出力されていれば起動に成功しています。ブラウザや wget / curl 等で http://127.0.0.1:8124 にアクセスすると HTTP レスポンスが返されます。</p>
<div class="codecolorer-container bash dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ curl http:<span style="color: #000000; font-weight: bold;">//</span>127.0.0.1:<span style="color: #000000;">8124</span><br />
Hello World</div></div>
<h3>ファイルを読み込んで表示</h3>
<p>上の Node.js のサンプルではプログラムから直接コンテンツを出力していましたが、メンテとかめんどそうなのでファイルからコンテンツを読み込んで出力するように改造します。</p>
<p>ファイル入出力には fs モジュールを使います。fs モジュールは Node.js 本体に含まれています。</p>
<p>fs.readFile 関数を使い index.html を読み込み出力するように改造した example.js です。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #006600; font-style: italic;">// fsモジュールも読み込む</span><br />
<span style="color: #003366; font-weight: bold;">var</span> http <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'http'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; fs <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'fs'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
http.<span style="color: #660066;">createServer</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>req<span style="color: #339933;">,</span> res<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// index.html を読み込んで表示</span><br />
&nbsp; &nbsp; fs.<span style="color: #660066;">readFile</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'index.html'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>err<span style="color: #339933;">,</span> content<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">throw</span> err<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; res.<span style="color: #660066;">writeHead</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">200</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><span style="color: #3366CC;">'Content-Type'</span><span style="color: #339933;">:</span><span style="color: #3366CC;">'text/html; charset=utf-8'</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; res.<span style="color: #660066;">end</span><span style="color: #009900;">&#40;</span>content<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">listen</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">8192</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'127.0.0.1'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>index.html の中身はこんな感じで、JavaScript と同じディレクトリに置きます。</p>
<div class="codecolorer-container html4strict dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;!doctype HTML&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">head</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">meta</span> <span style="color: #000066;">charset</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;UTF-8&quot;</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">title</span>&gt;</span>URL shortener by Node.js<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">title</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">head</span>&gt;</span><br />
<br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">h1</span>&gt;</span>URL shortener by Node.js<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">h1</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">form</span> <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;POST&quot;</span> <span style="color: #000066;">action</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/&quot;</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; Enter URL: <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;url&quot;</span> <span style="color: #000066;">size</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;50&quot;</span> <span style="color: #000066;">maxlength</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;256&quot;</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;submit&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Submit&quot;</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">form</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">body</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">html</span>&gt;</span></div></div>
<p>両方できたら先ほどと同じようにサーバを起動します。</p>
<div class="codecolorer-container bash dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">$ </span>node example.js</div></div>
<h4>非同期 I/O</h4>
<p>node.js でプログラムを書く場合、入出力は基本的に非同期 I/O を使います。上の例では fs.readFile を使用していますが、readFile はファイルの読み込みを完了するとエラーとファイルの中身を引数にコールバック関数を呼び出します。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">fs.<span style="color: #660066;">readFile</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'index.html'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>err<span style="color: #339933;">,</span> content<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// 読み込み完了時に呼び出される</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>コールバック関数の引数には、読み込み成功時は null と読み込んだコンテンツが、失敗時はそのまま例外送出可能なエラーオブジェクトが渡されます。</p>
<p>非同期 I/O とは I/O 関数呼び出し時にブロッキングしないことを意味します。上と似たようなコードを PHP で書くと以下のようになりますが、file_get_contents はコンテンツの読み込みが完了するまでプロセスの実行をブロッキングします。</p>
<div class="codecolorer-container php dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$content</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'index.html'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>Apache などのマルチプロセス（マルチスレッド）サーバでは、複数のプロセスでリクエスト応答を行います。サーバプロセス上で実行されるスクリプトでブロッキングが発生すると、そのプロセスの実行は単純に中断されます。中断中は他のサーバプロセスが他のリクエストの応答を行います。</p>
<p>一方 node.js はシングルプロセスウェブサーバですので、I/O 要求等によるブロッキングが発生するとサーバ全体の動作が中断してしまいます。もちろんそれではサーバとして用を成さないので、非同期 I/O を使って I/O 要求を発生時に別の実行可能な処理へサーバの処理を切り替えます。</p>
<p>Apache 上で普通の（同期 I/O を使った）スクリプトを書く方が簡単そうですが（実際に簡単ですけど）、node.js が注目された背景には <a href="http://www.hyuki.com/yukiwiki/wiki.cgi?TheC10kProblem">C10k 問題</a> があり、10000 (10k) を超えるクライアント接続に従来の（マルチプロセス／マルチスレッド型）ウェブサーバでは耐えられなくなってきたので、単一プロセス非同期 I/O ウェブサーバが必要とされている現状があります。</p>
<p>node.js というとサーバサイド JavaScript により学習コストの低下を期待する向きもあると思いますが、（非同期 I/O を使ってる関係で）ちょっとしたコーディングミスがサーバ全体の性能に影響を与える場合もありますのでプログラミングには注意が必要です。</p>
<h3>express フレームワークを使う</h3>
<p>小難しい話はこの辺にして、node.js 本体に含まれるモジュールだけでコーディングしているとソースが長ったらしくなるので、<a href="http://expressjs.com/">express フレームワーク</a>を使うようにソースを書き換えます。</p>
<p>先ほどまで全然説明していませんでしたが、モジュールの読み込みには require 関数を使います。require はモジュールオブジェクトを返します。モジュールオブジェクトは変数に代入して使用するのが一般的です。</p>
<p>express フレームワークでは、express.createServer でサーバオブジェクトを作成し、サーバオブジェクトの get メソッド等で URL マッパを設定します。以下の例ではサーバルート (/) へのリクエストに対し、sendfile でファイルの中身をレスポンスします。（上の例と同じ処理です。）</p>
<p>以下が修正したソースです。ついでにファイル名も変えます。server.js として保存してください。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #006600; font-style: italic;">// モジュールの読み込み</span><br />
<span style="color: #003366; font-weight: bold;">var</span> express <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'express'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// サーバを作成</span><br />
<span style="color: #003366; font-weight: bold;">var</span> app <span style="color: #339933;">=</span> express.<span style="color: #660066;">createServer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// '/' のリクエストハンドラ</span><br />
app.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>req<span style="color: #339933;">,</span> res<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; res.<span style="color: #660066;">sendfile</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'index.html'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// サーバを起動</span><br />
app.<span style="color: #660066;">listen</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">8124</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'127.0.0.1'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<h3>POST パラメータの処理と ejs テンプレート</h3>
<p>index.html からは HTTP POST でフォームデータを送信しますので、そのリクエストハンドラを記述していきます。</p>
<p>express で POST メソッドのリクエストハンドラを記述する場合、サーバオブジェクトの post メソッドで URL マッパを設定します。</p>
<p>HTTP 経由で受け取ったパラメータは、POST の場合は req.body にオブジェクトとして渡されます。あらかじめ app.use(express.bodyDecoder()) を呼び出しておかないと POST パラメータは処理してくれないので注意してください。</p>
<p>あとこのチュートリアルでは使ってませんが、URL の QueryString （PHP の $_GET） は req.query に渡されます。</p>
<p>また HTML コンテンツにデータを埋め込むため、<a href="https://github.com/visionmedia/ejs">ejs テンプレートエンジン</a>を使用するように変更します。ejs の 他に <a href="http://jade-lang.com/">Jade</a>、<a href="http://github.com/visionmedia/haml.js">Haml</a>、<a href="https://github.com/mauricemach/coffeekup">CoffeeKup</a>、<a href="https://github.com/kof/node-jqtpl">jQuery Templates</a> などのテンプレートエンジンも express と連動可能です。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #006600; font-style: italic;">// ejs モジュールも読み込む</span><br />
<span style="color: #003366; font-weight: bold;">var</span> express <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'express'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; ejs <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'ejs'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #003366; font-weight: bold;">var</span> app <span style="color: #339933;">=</span> express.<span style="color: #660066;">createServer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// bodyDecoder を指定しないと express が POST パラメータを処理してくれない</span><br />
app.<span style="color: #003366; font-weight: bold;">use</span><span style="color: #009900;">&#40;</span>express.<span style="color: #660066;">bodyDecoder</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// app.render('*.ejs') は ejs テンプレートエンジンで処理させる</span><br />
app.<span style="color: #660066;">register</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.ejs'</span><span style="color: #339933;">,</span> ejs<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
app.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>req<span style="color: #339933;">,</span> res<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// ejs テンプレートエンジンでレンダリング</span><br />
&nbsp; &nbsp; res.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'index.ejs'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
app.<span style="color: #660066;">post</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>req<span style="color: #339933;">,</span> res<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// req.body に POST パラメータがセットされるので</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// そのままテンプレートに渡す</span><br />
&nbsp; &nbsp; res.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'result.ejs'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; locals<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span> message<span style="color: #339933;">:</span> req.<span style="color: #660066;">body</span>.<span style="color: #660066;">url</span> <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
app.<span style="color: #660066;">listen</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">8124</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'127.0.0.1'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>テンプレートファイルは views サブディレクトリに配置します。views サブディレクトリにはページレイアウトを定義する layout.ejs が必要です。</p>
<div class="codecolorer-container html4strict dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;!doctype HTML&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">head</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">meta</span> <span style="color: #000066;">charset</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;UTF-8&quot;</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">title</span>&gt;</span>URL shortener by Node.js<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">title</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">head</span>&gt;</span><br />
<br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">h1</span>&gt;</span>URL shortener by Node.js<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">h1</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;%- body %&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">body</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">html</span>&gt;</span></div></div>
<p>views/index.ejs には先ほどの index.html の form 部分を記述します。</p>
<div class="codecolorer-container html4strict dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">form</span> <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;POST&quot;</span> <span style="color: #000066;">action</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/&quot;</span>&gt;</span><br />
&nbsp; Enter URL: <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;url&quot;</span> <span style="color: #000066;">size</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;50&quot;</span> <span style="color: #000066;">maxlength</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;256&quot;</span>&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;submit&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Submit&quot;</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">form</span>&gt;</span></div></div>
<p>views/result.ejs には message 置換変数を配置します。</p>
<div class="codecolorer-container html4strict dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;&lt;%<span style="color: #66cc66;">=</span> message %&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span></div></div>
<p>ejs では &lt;%= varname %> が html エスケープ付きのテンプレート変数出力、&lt;%- varname %> がエスケープなしの変数出力です。&lt;% code %> で JavaScript コードを直接記述することもできます。詳しくは <a href="https://github.com/visionmedia/ejs">https://github.com/visionmedia/ejs</a> をご覧ください。</p>
<h3>MySQL との連動</h3>
<p>今回のウェブアプリではテーブル短縮 URL 変換用テーブルをデータベースに保持します。テーブル定義はこんな感じです。</p>
<p>mysql コマンド等で予めデータベースに作成します。</p>
<div class="codecolorer-container sql dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> shorten_urls<br />
<span style="color: #66cc66;">&#40;</span>id &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">BIGINT</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span><br />
&nbsp;long_url &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">256</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNIQUE</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">COLLATE</span> utf8_bin<span style="color: #66cc66;">&#41;</span>;</div></div>
<p>node.js から MySQL データベースへ問い合わせを行うには、mysql モジュールの Client ライブラリを使用します。データベース問い合わせも I/O ですので非同期です。</p>
<p>以下が最終的に完成した短縮 URL ウェブアプリケーションプログラムです。base62 モジュールについては後述します。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #006600; font-style: italic;">// サーバのアドレスとポート</span><br />
<span style="color: #003366; font-weight: bold;">var</span> HOSTNAME <span style="color: #339933;">=</span> <span style="color: #3366CC;">'localhost'</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> PORT <span style="color: #339933;">=</span> <span style="color: #CC0000;">8124</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// MySQL データベース名、ユーザー名、パスワード</span><br />
<span style="color: #003366; font-weight: bold;">var</span> DBNAME <span style="color: #339933;">=</span> <span style="color: #3366CC;">'nodejs_url_shortener'</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> DBUSER <span style="color: #339933;">=</span> <span style="color: #3366CC;">'root'</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> DBPASSWD <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #003366; font-weight: bold;">var</span> sys <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'sys'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; express <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'express'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; ejs <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'ejs'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; Client <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'mysql'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">Client</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; base62 <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'./base62'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// MySQLデータベースに接続しcallbackを呼び出す</span><br />
<span style="color: #003366; font-weight: bold;">function</span> mysql<span style="color: #009900;">&#40;</span>callback<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> client <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Client<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; client.<span style="color: #660066;">database</span> <span style="color: #339933;">=</span> DBNAME<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; client.<span style="color: #660066;">user</span> <span style="color: #339933;">=</span> DBUSER<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; client.<span style="color: #660066;">password</span> <span style="color: #339933;">=</span> DBPASSWD<span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; client.<span style="color: #660066;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">throw</span> err<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; callback<span style="color: #009900;">&#40;</span>client<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #003366; font-weight: bold;">var</span> app <span style="color: #339933;">=</span> express.<span style="color: #660066;">createServer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
app.<span style="color: #003366; font-weight: bold;">use</span><span style="color: #009900;">&#40;</span>express.<span style="color: #660066;">bodyDecoder</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
app.<span style="color: #660066;">register</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.ejs'</span><span style="color: #339933;">,</span> ejs<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// ルート GET</span><br />
app.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>req<span style="color: #339933;">,</span> res<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; res.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'index.ejs'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// ルート POST</span><br />
app.<span style="color: #660066;">post</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>req<span style="color: #339933;">,</span> res<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// テンプレート変数</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> locals <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; error<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; short_url<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">null</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// パラメータをチェック</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>req.<span style="color: #660066;">body</span>.<span style="color: #660066;">url</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; locals.<span style="color: #660066;">error</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'Missing url parameter'</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span> &nbsp;<span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>req.<span style="color: #660066;">body</span>.<span style="color: #660066;">url</span> <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">256</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; locals.<span style="color: #660066;">error</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'url parameter too long'</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>locals.<span style="color: #660066;">error</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; res.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'result.ejs'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; locals<span style="color: #339933;">:</span> locals<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// idを短縮URLに変換して出力</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">function</span> render_short_url<span style="color: #009900;">&#40;</span>id<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; locals.<span style="color: #660066;">short_url</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'http://'</span> <span style="color: #339933;">+</span> HOSTNAME<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>PORT <span style="color: #339933;">!=</span> <span style="color: #CC0000;">80</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; locals.<span style="color: #660066;">short_url</span> <span style="color: #339933;">+=</span> <span style="color: #3366CC;">':'</span> <span style="color: #339933;">+</span> PORT<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; locals.<span style="color: #660066;">short_url</span> <span style="color: #339933;">+=</span> <span style="color: #3366CC;">'/'</span> <span style="color: #339933;">+</span> base62.<span style="color: #660066;">int_to_base62_string</span><span style="color: #009900;">&#40;</span>id<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; res.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'result.ejs'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; locals<span style="color: #339933;">:</span> locals<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// データベースに短縮URLを登録して表示</span><br />
&nbsp; &nbsp; mysql<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>client<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; client.<span style="color: #660066;">query</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #3366CC;">'INSERT INTO shorten_urls (long_url) VALUES (?)'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#91;</span>req.<span style="color: #660066;">body</span>.<span style="color: #660066;">url</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>err<span style="color: #339933;">,</span> results<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// キー重複は無視</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>err <span style="color: #339933;">&amp;&amp;</span> err.<span style="color: #660066;">number</span> <span style="color: #339933;">!=</span> Client.<span style="color: #660066;">ERROR_DUP_ENTRY</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.<span style="color: #660066;">end</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">throw</span> err<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// インサート成功</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>err<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; render_short_url<span style="color: #009900;">&#40;</span>results.<span style="color: #660066;">insertId</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// インサート失敗時はlong_urlをキーで検索する</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.<span style="color: #660066;">query</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #3366CC;">'SELECT id FROM shorten_urls WHERE long_url = ?'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#91;</span>req.<span style="color: #660066;">body</span>.<span style="color: #660066;">url</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>err<span style="color: #339933;">,</span> results<span style="color: #339933;">,</span> fields<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.<span style="color: #660066;">end</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">throw</span> err<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>results.<span style="color: #660066;">length</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.<span style="color: #660066;">end</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">throw</span> <span style="color: #003366; font-weight: bold;">new</span> Error<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Something wrong'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.<span style="color: #660066;">end</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; render_short_url<span style="color: #009900;">&#40;</span>results<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// 短縮URLをリダイレクト</span><br />
app.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/^\/([0-9A-Z]{5,})$/</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>req<span style="color: #339933;">,</span> res<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; mysql<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>client<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// idからurlを検索してリダイレクト</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; client.<span style="color: #660066;">query</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #3366CC;">'SELECT long_url FROM shorten_urls WHERE id = ?'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#91;</span>base62.<span style="color: #660066;">base62_string_to_int</span><span style="color: #009900;">&#40;</span>req.<span style="color: #660066;">params</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>err<span style="color: #339933;">,</span> results<span style="color: #339933;">,</span> fields<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.<span style="color: #660066;">end</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">throw</span> err<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.<span style="color: #660066;">end</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>results.<span style="color: #660066;">length</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// データが無い</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res.<span style="color: #660066;">send</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Not Found'</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">404</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res.<span style="color: #660066;">redirect</span><span style="color: #009900;">&#40;</span>results<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">long_url</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
app.<span style="color: #660066;">listen</span><span style="color: #009900;">&#40;</span>PORT<span style="color: #339933;">,</span> HOSTNAME<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>短縮 URL を展開する際、URL に埋め込まれた ID を正規表現でパースして req.params 経由で受け取ります。この辺は express の機能を使ってますので、詳しくは express のマニュアルの <a href="http://expressjs.com/guide.html#Routing">Routing</a> の項をご覧ください。</p>
<p>コードの修正が終わったら、result.ejs はエラーメッセージも埋め込めるように少し修正します。</p>
<div class="codecolorer-container html4strict dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;% if <span style="color: #66cc66;">&#40;</span>error<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> %&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;&lt;%<span style="color: #66cc66;">=</span> error %&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span><br />
<span style="color: #009900;">&lt;% <span style="color: #66cc66;">&#125;</span> else <span style="color: #66cc66;">&#123;</span> %&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;</span>Short url is <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;&lt;%= short_url %&gt;</span></span>&quot;&gt;<span style="color: #009900;">&lt;%<span style="color: #66cc66;">=</span> short_url %&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span><br />
<span style="color: #009900;">&lt;% <span style="color: #66cc66;">&#125;</span> %&gt;</span></div></div>
<p><a href="https://github.com/visionmedia/ejs">ejs</a> テンプレートエンジンでは、&lt;% %> 内に JavaScript のコードをそのまま記述できます。</p>
<h4>mysql モジュールの使い方</h4>
<p>MySQL データベースへの問い合わせは、mysql モジュールの Client クラスを使用して行います。</p>
<p>データベース問い合わせも I/O ですので非同期で実行します。データベース接続やクエリが完了した際に実行される処理をコールバック関数で指定します。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> Client <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'mysql'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">Client</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> client <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Client<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// 接続先データベースを指定</span><br />
client.<span style="color: #660066;">database</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'DB'</span><span style="color: #339933;">;</span><br />
client.<span style="color: #660066;">user</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'USER'</span><span style="color: #339933;">;</span><br />
client.<span style="color: #660066;">password</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'PASSWORD'</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// データベースへ接続する</span><br />
client.<span style="color: #660066;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">throw</span> err<span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// クエリを実行する</span><br />
&nbsp; &nbsp; client.<span style="color: #660066;">query</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;SELECT * FROM T WHERE var = ?&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span><span style="color: #003366; font-weight: bold;">var</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>err<span style="color: #339933;">,</span> results<span style="color: #339933;">,</span> fields<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">throw</span> err<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>connect メソッドのコールバック関数には、接続成功時は null が、失敗時は例外送出可能なエラーオブジェクトが渡されます。</p>
<p>query メソッドの引数は SQL、バインド変数、コールバック関数です。バインド変数とコールバック関数はそれぞれ省略可能ですので、以下のコードはすべて有効です。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">client.<span style="color: #660066;">query</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;SQL&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
client.<span style="color: #660066;">query</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;SQL&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span><span style="color: #003366; font-weight: bold;">var</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
client.<span style="color: #660066;">query</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;SQL&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>err<span style="color: #339933;">,</span> results<span style="color: #339933;">,</span> fields<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>query メソッドのコールバック関数の引数は、SQL が SELECT の場合は function(err, results, fields) となります。SELECT 以外の場合は function(err, fields) です。</p>
<p>SELECT の場合も SELECT 以外の場合も、err には SQL 実行成功時 は null が、失敗時は例外送出可能なエラーオブジェクトが渡されます。</p>
<p>results は SELECT された列の配列です。配列の要素は列名をキーに持つオブジェクトです。SELECT 時の fields には SELECT された列定義が返されます。</p>
<p>SELECT 以外の場合、fields には affectedRows や insertId など SQL の実行結果を表す情報が渡されます。</p>
<p>MySQL モジュールの API の詳細については、<a href="https://github.com/felixge/node-mysql">https://github.com/felixge/node-mysql</a> をご覧ください。</p>
<h4>非同期コードでの例外処理</h4>
<p>非同期で実行される箇所で例外を送出する場合は注意が必要です。このように単純に例外を送出するとサーバが終了します。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">client.<span style="color: #660066;">query</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;sql...&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>err<span style="color: #339933;">,</span> results<span style="color: #339933;">,</span> fields<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">throw</span> err<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// ...</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>サーバを終了させずにユーザーにエラーを表示する場合は、例外ではなく普通にコンテンツを表示します。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">client.<span style="color: #660066;">query</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;sql...&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>err<span style="color: #339933;">,</span> results<span style="color: #339933;">,</span> fields<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; res.<span style="color: #660066;">send</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Not Found'</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">404</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// ...</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>express には例外送出によりエラー出力をフックするための仕組みが app.error() として用意されていますが、非同期部分から例外を送出してもこの仕組みで補足されませんので例外によらず直接エラー出力を行う必要があるようです。</p>
<h3>自作モジュール</h3>
<p>完成したウェブアプリケーションでは、短縮 URL の id 部分に、base62 の数値を 0-9a-zA-Z で文字列表現するモジュールを使用していますが、このモジュールは自作したものです。（機能的に分けただけで npm からインスコできる形のモジュールではありません。）</p>
<p>自作モジュールのロードも require で行いますが、モジュール名に ./ を付けて require(&#8216;./base62&#8242;) とすることでモジュール検索パスを無効にしています。</p>
<p>モジュールは普通の JavaScript ファイルとして作成します。require では拡張子を省略していますので、base62 モジュールのファイル名は base62.js です。</p>
<p>モジュールから外部へエクスポートするシンボルは、exports の要素にします。base62 モジュールでは int_to_base62_string と base62_string_to_int 関数をエクスポートします。</p>
<div class="codecolorer-container javascript dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> base62_map <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; int_map <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #003366; font-weight: bold;">var</span> x <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> s <span style="color: #339933;">=</span> String<span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; base62_map.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>s<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; int_map<span style="color: #009900;">&#91;</span>s<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> x<span style="color: #339933;">++;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #339933;">=</span> <span style="color: #3366CC;">'a'</span>.<span style="color: #660066;">charCodeAt</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">26</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> s <span style="color: #339933;">=</span> String.<span style="color: #660066;">fromCharCode</span><span style="color: #009900;">&#40;</span>a <span style="color: #339933;">+</span> i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; base62_map.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>s<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; int_map<span style="color: #009900;">&#91;</span>s<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> x<span style="color: #339933;">++;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #003366; font-weight: bold;">var</span> A <span style="color: #339933;">=</span> <span style="color: #3366CC;">'A'</span>.<span style="color: #660066;">charCodeAt</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">26</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> s <span style="color: #339933;">=</span> String.<span style="color: #660066;">fromCharCode</span><span style="color: #009900;">&#40;</span>A <span style="color: #339933;">+</span> i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; base62_map.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>s<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; int_map<span style="color: #009900;">&#91;</span>s<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> x<span style="color: #339933;">++;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
exports.<span style="color: #660066;">int_to_base62_string</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>num<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> ret <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>num <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ret <span style="color: #339933;">=</span> base62_map<span style="color: #009900;">&#91;</span>num <span style="color: #339933;">%</span> <span style="color: #CC0000;">62</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> ret<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; num <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>num <span style="color: #339933;">/</span> <span style="color: #CC0000;">62</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> head <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> n <span style="color: #339933;">=</span> <span style="color: #CC0000;">5</span> <span style="color: #339933;">-</span> ret.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> n <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> <span style="color: #339933;">--</span>n<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; head <span style="color: #339933;">+=</span> <span style="color: #3366CC;">'0'</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>head<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ret <span style="color: #339933;">=</span> head <span style="color: #339933;">+</span> ret<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> ret<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
exports.<span style="color: #660066;">base62_string_to_int</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>str<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> ret <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> str.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> s <span style="color: #339933;">=</span> str.<span style="color: #660066;">substr</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ret <span style="color: #339933;">*=</span> <span style="color: #CC0000;">62</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ret <span style="color: #339933;">+=</span> int_map<span style="color: #009900;">&#91;</span>s<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> ret<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<h3>アプリを動かしてみる</h3>
<p>完成したので短縮URLウェブアプリを動かしてみます。</p>
<div class="codecolorer-container bash dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">$ </span>node server.js</div></div>
<p>サーバが起動したらブラウザで <a href="http://localhost:8124">http://localhost:8124</a> にアクセスします。</p>
<p><a href="http://sakuratan.biz/blog/wp-content/uploads/2011/01/node1.png"><img src="http://sakuratan.biz/blog/wp-content/uploads/2011/01/node1-300x180.png" alt="URL Shortener" title="URL Shortener" target="_blank" width="300" height="180" class="aligncenter size-medium wp-image-3296 capture" /></a></p>
<p>短縮したい URL を入力して submit を押すと URL が短縮されます。</p>
<p><a href="http://sakuratan.biz/blog/wp-content/uploads/2011/01/node2.png"><img src="http://sakuratan.biz/blog/wp-content/uploads/2011/01/node2-300x180.png" alt="URL Shortener" title="URL Shortener" target="_blank" width="300" height="180" class="aligncenter size-medium wp-image-3302 capture" /></a></p>
<p>そのまま短縮された URL をクリックすると元の URL にリダイレクトします。</p>
<p><a href="http://sakuratan.biz/blog/wp-content/uploads/2011/01/google.png"><img src="http://sakuratan.biz/blog/wp-content/uploads/2011/01/google-300x180.png" alt="google" title="google" target="_blank" width="300" height="180" class="aligncenter size-medium wp-image-3300 capture" /></a></p>
<p>チュートリアルは以上です。</p>
<p>最近の流行りは XMLHttpRequest や jsonp とか使った Facebook の BigPipe みたいな感じのウェブアプリだと思いますので、上で作ったようなちょいと古めのウェブアプリを node.js で作りたいかと聞かれたら答えは明らかに NO ですが、node.js の仕組みを覚えるにはこんな感じの簡単なものから入るのがよろしいんじゃないかと思います。</p>
<p>個人的には今のところ node.js を使う予定はありませんが、どうせ覚えるなら早めの方がよろしいんじゃないでしょうか。</p>
<p>んでわ</p>
<p>P.S. ずっと Node.js だと思い込んでたもんで最初先頭大文字で表記してたんですが、よく見りゃ node.js だったので後から直しました。キャプチャとかソース中の表記は直すのめんどいんで Node.js のままにしてます。サーセン</p>
]]></content:encoded>
			<wfw:commentRss>http://sakuratan.biz/archives/3101/feed</wfw:commentRss>
		<slash:comments>1033</slash:comments>
		</item>
	</channel>
</rss>
