Node クックブック - izudon/izudon.github.io GitHub Wiki
- 6章 Express で開発をスピードアップ
express
- 5章 Websocket を使って Ajax を超える
websocket-
socket.ioサーバからクライアントの(またはその逆)メソッドを呼び出せる。- 'コールバック' という。
-
nowNowjs コールバックを一段と簡単にした。 socket.io-client
- 4章 データベース接続
-
ya-csvCSVファイル -
mysqlMySQL -
mongodbMongoDB -
mongoskinmongodbのスーパーセット -
cradleCouchDB - ACID をサポート。- CouchDB は REST API 準拠なので http.request で全部できなくもない。
- MongoDB も 4.0 からトランザクション(ACID 特性)をサポートした。
-
redisRedis - メモリ内に収まる程度のデータの場合、最適な選択肢。 -
hiredisCで書いたredis。Redis 提供。redisよりも高速。
-
- 3章 データのシリアル化
- JSON は
JSON.dtringify()JSON.parse()がビルトインされている。 -
xml2jsXMLファイル・データを扱う -
colors色をつけやすくする
- JSON は
- 2章 HTTPオブジェクトをより深く
connectformidable
- 1章 Webサーバを立てる
-
http- HTTP サーバや HTTP 接続を構築したりする場合 -
path- パスのベースネームを取得したりする場合など -
fs- ファイルシステムのファイルを利用する場合 -
url- クエリストリングを取り出す場合など -
querystring- ポストデータを連想記憶配列化する場合など
-
$ sudo npm install -g formidable<form method="post" enntype="multipart/form-data">
<input type="file" name="userfile1"><br>
<input type="file" name="userfile1"><br>
<input type="submit">
</form>- PHP では
$_POST['fieldname']を使える。- POST データを
$_POST[]に格納するまでブロッキングされているため。
- POST データを
- Node ではどうやるかはすべて開発者に委ねられている。
-
querystringモジュール-
querystring.parse( postData )でポストデータを連想記憶配列化できる。
-
-
utilモジュール-
util.inspect(postDataObject)で、オブジェクトをJSON形式で出力。
-
$ sudo npm install -g connect-
connectモジュールによるサーバの生成- メソッドチェーンで様々な設定をつなぎ、
最後にコールバック関数をチェーンする。
- メソッドチェーンで様々な設定をつなぎ、
var app = connect()
.use( connect.bodyParser() )
.use( connect.limit('64kb') )
.use( function( req, res ){
;
}Node はミニマリストアプローチのため堅牢さは実装者に大きく依存する(!!)。
-
path.noemalize()- パスの正規化により 相対ディレクトリ攻撃 と ヌルバイト攻撃 を
回避しようとするもの。- 相対ディレクトリ攻撃
http://server.name/../../../../../passwd - ヌルバイト攻撃
http://server.name/secure.js%00/index.html
- 相対ディレクトリ攻撃
- パスの正規化により 相対ディレクトリ攻撃 と ヌルバイト攻撃 を
-
path.basename()- ベースネームのみ取得(前回までのコード)= 比較的安全
- 請求できるファイル名をこちらから限定してしまう。
- キャッシュ機能を備えた、成熟したモジュール。
- RFC2616(HTTP 1.1)準拠。
データをディスクから全部読み込んでしまうのではなく
response に pipe することができる。
-
fs.createReadStream()<- readStresm オブジェクトを返す。 -
fs.createReadStream().on( 'open', function(){ ... } );- オープン時にイベントハンドラを仕掛ける。
-
fs.createReadStream().once( 'open', function(){ ... } );- オープン時に1度しか使わない処理なので .once() で仕掛ける。
- イベントが発生してイベントハンドラの実行が終わり次第イベントリスナは解放。
-
fs.createReadStream().once( 'error', function( e ){ ... } );- エラーハンドラを仕掛けられる。
-
stream.pipe( response )- これでフローを制御しながら延々とやっておいてくれる。
-
readStreamクラス-
EventEmitterクラスを継承 - -> 豊富なイベントハンドラ
-
-
readStreamクラス-
inputStreamクラスの子クラス? - ->
pipe()メソッドでoutputStreamにパイプできる?
-
-
stream.on( 'data', function( data ){ ... } );-
dataイベントは、ディスクから1チャンクデータを取得するたびに呼ばれる。
1チャンクのデフォルトは 64KB。
-
- Buffer クラス
- インスタンス生成時にサイズ指定してまとまった大きさのメモリを確保できる。
変数の代わりにここに今回は溜めこんでる。 - ここでは
stat()したときのstats.sizeつまりファイルサイズ分の
領域をあらかじめ確保し、dataイベント毎に1チャンク分を足していってる。 - -> あまりにも大きいファイルがあると領域確保失敗の恐れ。
(バッファオーバーフロー:次項で対策)
- インスタンス生成時にサイズ指定してまとまった大きさのメモリを確保できる。
- キャッシュをもうクラスとして実装しちゃった。
- サイズ上限を決めそれ以下のファイルのみキャッシュすることにした。
- JavaScript の変数は関数スコープ。
- ブロックスコープではない!
- 中途半端な場所に現れた変数宣言(
var s;等)はすべて
関数冒頭に引っ張り上げられて解釈される。 - 書籍『インタラクティブ・データビジュアライゼーション』に書いてあった。
- スクリプト内変数に情報を貯めておけば、次のセッションでも使いまわせる。
-
Date.now()で現在日時、
fs.stat()でファイル最終更新日時等(ctime, mtime, atime)が取得できる。
- fs モジュール
- ファイルシステムのファイルを扱うモジュール。
-
fs.exists( <pathname>, function( exists ){ ... } );-
<pathname>のファイルが存在するか調べる。 - 相対パス指定の起点はスクリプト(
server.js)の実行ディレクトリ。 - 存在すれば
true存在しなければfalseを引数に入れて
コールバック関数を呼び出す。
-
-
fs.readFile( <pathname>, function( err, data ){ ... } );-
<pathname>のファイルを読み込み、コールバック関数を呼ぶ。 -
errなんらかのエラーがあればtrueが格納。 -
data読み込んだデータが格納。
-
- decodeURI()
-
%20などを解釈してデコードする
-
- http モジュール
- HTTP リクエストとレスポンスを処理する。
-
http.createServer( function( request, response ){ ... } ).listen(8080);- HTTP サーバプロセスを作成し、ポート 8080番 を開いて接続を待つ。
- 具体的な処理はコールバック関数の中に。
-
request.url- リクエストのURLが格納されてくる。
-
response.writeHead( 200, { 'Content-Type': 'text/html' } )- ステータスコード 200 番で応答を作成。
- Content-Type などその他もろもろのヘッダ情報は第2引数のハッシュに指定。
-
response.end( 'Wahoo!' )- 'Wahoo!' と出力してレスポンスを終える。
response.finishedがtrueになる。
- 'Wahoo!' と出力してレスポンスを終える。
- path モジュール
- path.baseneme() でベースネームを取り出せる。
-
path.basename( '/foo/bar/baz.html' )->baz.html -
path.basename( '/foo/bar/baz.html', '.html' )->baz
- url モジュール
- クエリストリングを取り出せる。
url.parse( decodeURL( request.url ), true ).query.id
