書籍「Node.js超入門」のまとめ。
点数
87点
感想
とてもわかりやすかった。
今後Node.jsを実務でどう使っていくか、は考えていかなければならないと思う。
Node.jsとは
Javascriptのランタイム環境。
V8エンジンというJavaScriptランタイムエンジンを使用している。
(ver.10からはv8エンジンに依存しなくなったらしい)
最近は、JavaScriptのライブラリがNode.jsのライブラリ管理ツールを利用しているため、JavaScriptの開発プラットフォームの役割を果たすようになっている。
webサーバー機能のためのライブラリがある。
Expressという有名なフレームワークがある。
2つのバージョン
- 偶数バージョン=LTS
- 奇数バージョン=新仕様
通常は、偶数バージョンを使用する。
- ver.6:2016年4月に登場。2018年4月までサポート。2019年4月までメンテナンス。
- ver.8:2017年5月に登場。2019年1までサポート。2019年12月までメンテナンス。
- ver.10:2018年4月に登場。2020年4までサポート。2021年4月までメンテナンス。
npm
インストールしたいフォルダに移動してnpm install -g パッケージ名
-gはグローバルオプションでNode.js本体にインストールする。
サーバへアップする場合などは-gを外し、カレントフォルダへインストールする。
WEBサーバを動かす(コマンドライン)
node
.editor
require('http').createServer((rq,rs)=>{rs.end('Hello Node.js!');}).listen(3000);
Ctrl+D
# http://localhost:3000でアクセス可能
node
の後はjavascript文を実行できる
node
console.log('Hello');
.editor
でエディタモードに切り替わる。Ctrl+Dで入力完了、Ctrl+Cでキャンセル。
WEBサーバを動かす(ファイル)
const http = require('http');
var server = http.createServer(
(request, response)=>{
response.setHeader('Content-type', 'text/html');
response.write('<html lang=""ja""><head><meta charset=""utf-8""></head><body>');
response.write('<hr>ハロー<hr></body></html>');
response.end();
}
);
server.listen(3000);
ディレクトリに移動してnode app.js
で実行
Node.jsではrequire(モジュール名)
でモジュールを使えるようになる。
最初から使える状態のオブジェクトにしておくと、知らずに同名のオブジェクト名で新たにオブジェクトを作ってしまうかもしれないため。
requestはhttp.ClientRequestオブジェクト
responseはhttp.ServerResponseオブジェクト
fsオブジェクト
- オブジェクト取得
var fs = require('fs');
- 非同期処理でファイル読み込み
fs.readFile('hello.txt', 'UTF-8', readFinish);
- 同期処理でファイルを読み込み
fs.readFileSync('hello.txt', 'UTF-8');
readFileメソッドはどんな大きさのファイルでも即時に実行を終え、次に進む。
実際の読み込みはバックグラウンドで行われ、読み込みが完了したら第3引数の関数を実行する。
そこで読み込み後の処理などを行う、という仕組みになっている。
const http = require('http');
const fs = require('fs');
var server = http.createServer(
(request, response)=>{
fs.readFile('hello.html', 'UTF-8', (error, data)=>{
response.setHeader('Content-type', 'text/html');
response.write(data.replace(/<hr>/g, '<hr style=""border-color:red"">'));
response.end();
});
}
);
server.listen(3000);
ファイル書き込み
fs.writeFile('data.txt', 'hogehoge', (error)=>{
if (error) {
throw error;
}
});
追記する場合はappendFileメソッドを使う。
EJS
Embedded JavaScript templates
Node.jsのテンプレートエンジンの1つ。
npmコマンドでインストールできる。npm install -g ejs
require('ejs');
で読み込み- テンプレートファイルは拡張子を.ejsとするのが一般的
- 変数は<%=hoge %>(エスケープしない場合は<%- %>)
ejsオブジェクト.render(ejsテキスト, {変数名: 値}));
でHTML取得
const http = require('http');
const fs = require('fs');
const ejs = require('ejs');
var server = http.createServer(
(request, response)=>{
data = ejs.render(fs.readFileSync('index.ejs', 'UTF-8'), {name: 'ゲストさん'});
response.setHeader('Content-type', 'text/html');
response.write(data);
response.end();
}
);
server.listen(3000);
EJSでのループ
<% %>
で囲むだけ。
<% for (var key in data) { %>
<% } %>
EJSのパーシャル
- renderにfilenameという名前でインクルードするパスを指定する
<%- include('ファイル名', パラメータ) %>
data = ejs.render(fs.readFileSync('index.ejs', 'UTF-8'), {name: 'ゲストさん', filename: './'});
※filenameはファイル名を入れても無視され、ディレクトリがインクルードパスとして使われる。よって、filename: ‘./aaa.txt’など存在しないファイルを指定しても、./と同じ扱いとなる
ルーティング
http://localhost:3000/hoge.jpgなどとやってもindex.ejs(readFileSyncで読んだファイル)が表示される。
よって、<img src="./hoge.jpg"/>
とやっても画像は表示されない。
⇒URLオブジェクトを利用する
require('url');
で読み込みurlオブジェクト.parse(ClientRequestオブジェクト.url);
でパース済みオブジェクトを取得パース済みオブジェクト.pathname
によって分岐させる
const http = require('http');
const fs = require('fs');
const ejs = require('ejs');
const url = require('url');
var server = http.createServer(
(request, response)=>{
var parsed_url = url.parse(request.url);
switch (parsed_url.pathname) {
case '/':
data = ejs.render(fs.readFileSync('index.ejs', 'UTF-8'), {name: 'ゲストさん'});
response.setHeader('Content-type', 'text/html');
response.write(data);
response.end();
break;
}
}
);
server.listen(3000);
クエリストリングの取得
- parseメソッドの第2引数をtrueにする
- パース済みオブジェクトのqueryプロパティに格納されている
(parseメソッドの第2引数がfalse(または未指定)だとvar=hogeという文字列になる)
const http = require('http');
const fs = require('fs');
const ejs = require('ejs');
const url = require('url');
var server = http.createServer(
(request, response)=>{
var parsed_url = url.parse(request.url, true);
switch (parsed_url.pathname) {
case '/other':
var query = parsed_url.query;
data = ejs.render(fs.readFileSync('other.ejs', 'UTF-8'), {name: query.name});
}
}
);
server.listen(3000);
POST値の取得
require('querystring');
で読み込みClientRequestオブジェクト.method
でリクエストメソッドを取得可能- ClientRequestオブジェクトのonメソッドでイベントを設定する
dataイベントが受信時、endイベントが受信完了時
※文字列が長い場合には何回かに別れて送られてくるため、dataイベントも複数回コールされる querystringオブジェクト.parse(body);
でパース
const querystring = require('querystring');
// ~省略~
switch (parsed_url.pathname) {
case '/other':
if (request.method === 'POST') {
var body = '';
request.on('data', (data) => {
body += data;
});
request.on('end', () => {
var params = querystring.parse(body);
// 処理
});
}
}
アプリケーション変数
WEBサーバは実行中の状態で待ち受けているため、グローバル変数は常に保持されている。
よって、グローバル変数はいつ誰がアクセスしても同じ値を得ることができるアプリケーション変数として使うことができる。
var msg = 'no message';
// として
var params = querystring.parse(body);
msg = params.message;
data = ejs.render(fs.readFileSync('./other.ejs', 'UTF-8'), {msg : msg );
クッキー
// 保存
response.setHeader('Set-Cookie', ['age=30']);
// 取得
var data = request.headers.cookie.split(';');
for (var i in data) {
console.log(data[i]); // xx=xxという文字列なのでsubstringなどで自力で取り出す
}
値がマルチバイト文字列の場合はencodeURL、decodeURIでエスケープする必要あり。
※escape, unescapeは廃止予定なので使わない
コメント