【Node.js】cookieを使ったクライアント ~ サーバー間のデータのやりとりサンプル
ブラウザにデータを保存するという役割でいうと、localStorage
と cookie
が代表的かと思いますが、localStorage
はクライアント側のみで使える機能で、サーバからは扱えません。
そのためクライアントとサーバ間のデータのやり取りではcookieを使うことで手軽に行えます。
というわけで理解を深めるために書籍のサンプルデータを参考に簡単なサンプルを作ってみました。
仕様
- cookieに
userName
がなければ「ゲスト」と表示する - cookie に
userName
があればその値を表示する - テキストボックスに入力してsubmitしたら、その値がcookieの
userName
として保存される
というシンプルな作りです。
コード
index.ejs(クライアント側)
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title><%= title %></title> </head> <body> <header> <h1><%= title %></h1> </header> <main> <p>こんにちは、<%= userName %>さん</p> <form action="/" method="post"> <p>ユーザー名: <input type="text" name='userName'><input type="submit" value="送信"></p> </form> </main> </body> </html>
app.js(サーバ側)
const http = require('http'); const fs = require('fs'); const url = require('url'); const qs = require('querystring'); const ejs = require('ejs'); const INDEX_PAGE = fs.readFileSync('./index.ejs', 'utf8'); /** * クッキーの値を取得 */ function getCookie(key, request) { const cookieData = request.headers.cookie !== undefined ? request.headers.cookie : ''; const datas = cookieData.split(';').map(data => data.trim()); const msgKeyValue = datas.find(data => data.startsWith(`${key}=`)); if (msgKeyValue === undefined) return ''; const msgValue = msgKeyValue.replace(`${key}=`, ''); return unescape(msgValue); } /** * クッキーの値を設定 */ function setCookie(key, value, response) { const escapedValue = escape(value); response.setHeader('Set-Cookie', [`${key}=${escapedValue}`]); } function getFromClient(request, response) { const urlParts = url.parse(request.url, true); const pathName = urlParts.pathname; switch (pathName) { case '/': if (request.method === 'POST') { let body = ''; request.on('data', data => { body += data; }); request.on('end', () => { const postData = qs.parse(body); setCookie('userName', postData.userName, response); response.writeHead(303, { Location: '/' }); response.end(); }); } else { const userNameFromCookie = getCookie('userName', request); const userName = userNameFromCookie ? userNameFromCookie : 'ゲスト'; const content = ejs.render(INDEX_PAGE, { title: 'Index', userName }); response.writeHead(200, { 'Content-Type': 'text/html' }); response.write(content); response.end(); } break; default: response.writeHead(200, { 'Content-Type': 'text/plain' }); response.write('No page...'); response.end(); break; } } const server = http.createServer(getFromClient); server.listen(3000); console.log('====== Server start!! ======');
解説・まとめ
ポイントとしては、クッキーの読み書きのタイミングかと思います。
サーバーサイド初心者の自分にとっては最初ちゃんと理解できなかったのですが、今回はフォーム上からcookieに登録する仕様なので、POST完了後のタイミングでその処理を行う必要があります。
POST完了後、response.setHeader('Set-Cookie', [key=value])
の形でレスポンスのヘッダーにCookieを渡すことができます。これによりクライアントのcookieに保存されます。
ページ表示時(GET)には、cookieを読み取る必要があるため、request.header.cookie
でcookieを参照します。
今回はcookieの userName
というキーに値がなければ 「ゲスト」と表示しています。
取得したらそれをテンプレート側に渡してあげるだけとなります。
機能追加として、たとえばユーザーの訪問回数をカウントするのであれば、GET時のログを貯めておいてそれをユーザー名をキーにしてカウントすれば簡単に実装できそうです。