こんにちは、つるぴよ@(tsurupiyoo)です!
JavaScriptを勉強してフロントエンジニアを目指しています!
今回は学習ロードマップの1番目「マンガJavaScript」を読んでのまとめ、アウトプットを記事にしています。
JavaScriptの学習方法
1. マンガJavaScript読む
2. 改訂新版JavaScript本格入門読む
3. Webページで使われているような部品をJSで作る(タブ、フォーム、ドロワーメニュー、スライドショー、オリジナルゲームを作る、検索ボックス、ページネーション)
4. APIリクエストで得たデータでコンテンツを作る— フロントエンドエンジニア (@terrace_tech) June 30, 2020
マンガJavaスクリプト第21話 クッキーの利用
Webページ上のJavaScriptではローカル(パソコンのハードディスクなどの保存領域)へのデータの読み書きはセキュリティ上の理由でできません。
そこで「クッキー」という安全にデータの読み書きができる仕組みがあります。
今回は「クッキー」について学んでいきます。
「クッキー」の保存と読み込み
「document.cookie」プロパティ
「クッキー」の保存と読み込みを行うプロパティ。
このプロパティにキーと値のセットを1つずつ代入して「クッキー」に値を保存します。
document.cookie = "key1=value1;"; document.cookie = "key2=value2;";
書き込んだデータを取り出すとこのようになります
alert(document.cookie);
key1=value1; key2=value2;
「クッキー」の保存と読み込みの違い
「document.cookie」を利用した「クッキー」の保存と読み込みは以下の注意が必要です!
保存時時(値を代入した時)の値と読み込み時(値を参照)の値が異なる。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <script> function save() { // 対象要素を空に var ele = document.getElementById("view"); ele.innerHTML = ""; // 書き込み1つ目 document.cookie = "key1=value1;"; ele.innerHTML += document.cookie + "<br>"; // 書き込み2つ目 document.cookie = "key2=value2;"; ele.innerHTML += document.cookie + "<br>"; } </script> </head> <body> <input type="button" onClick="save();" value="保存"> <br> <div id="view"></div> </body> </html>
「保存」ボタンをクリックすると以下のような結果が表示されます。
key1=value1
key1=value1; key2=value2
「書き込み2つ目」で「document.cookie」に「key2=value2;」が代入されているのにも関わらず「document.cookie」の中身は「key1=value1; key2=value2]」になっています。
このことから保存時の値と読み込み時の値が違うことがわかります。「クッキー」の保存時と読み込み時の処理についてみていきましょう。
【保存時】 「document.cookie」に新しい値を代入する。 内部的に『値を書き換える関数』が呼び出される。 「値を書き換える関数」の中で、与えられた値を解釈する。 「値を書き換える関数」の中で、解釈した値をブラウザに保存する。
【読み込み時】 1. 『document.cookie』から値を取り出そうとする。 2. 内部的に『値を読み込む関数』が呼び出される。 3. 『値を読み込む関数』の中で、ブラウザから全ての値を読み出して、文字列にして返す。
クッキーの保存条件
クッキーに値を保存する時は、キーの値のセットとともに
いくつかの保存条件を設定できます。
document.cookie = "key1=value1; expires=Thu, 22 Apr 2010 09:00:26 UTC";
「expires」とは?
有効期限を表すキー。
設定しなかった場合ブラウザを閉じた時点で「クッキー」の値は失われる。
値は「Wdy, DD-Mon-YYYY HH:MM:SS GMT」または
日付オブジェクトの「toGMTString」メソッドの値
// 有効期限を1年後に var d = new Date(); d.setFullYear(d.getFullYear() + 1); // クッキーの保存 document.cookie = "key1=value1; expires=" + d.toGMTString();
マンガの中に登場したプログラムについて
ちょっと長いプログラムだけどみていきましょう!
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <script> function save() { // 『input0』『input1』要素の値を取得して、クッキーに書き込み writeCookie("input0", document.getElementById("input0").value, 1); writeCookie("input1", document.getElementById("input1").value, 1); } function load() { // クッキーから読み込んだ値を、『input0』『input1』要素に設定 document.getElementById("input0").value = readCookie("input0"); document.getElementById("input1").value = readCookie("input1"); } function writeCookie(key, value, hours) { if (key == "") return; // 現在時刻に、引数『hours』を加えた時間を作成 var d = new Date(); d.setHours(d.getHours() + hours * 1); // 作成した時間を、設定として配列に格納 var options = new Array(); options.push("expires=" + d.toGMTString()); // 引数『key』『value』を元にした設定と、時刻の設定を、 // 文字列結合してクッキーに書き込み document.cookie = escape(key) + "=" + escape(value) + "; " + options.join("; "); // 『key=value; expires=時間』を書き込み } function readCookie(key) { if (key == "") return; // クッキーの文字列『key1=value; key2=value; …』から、 // 引数の『key』を元に、正規表現で値を検索 var re = new RegExp(escape(key) + "=(.*?)(?:;|$)"); if (document.cookie.match(re)) return unescape(RegExp.$1); return ""; } </script> </head> <body> <input type="text" id="input0" value=""><br> <input type="text" id="input1" value=""><br> <input type="button" onClick="save();" value="保存"> <input type="button" onClick="load();" value="読み込み"><br> </body> </html>
このようなページが出来上がります。
文字を入力して保存をしてからページを再読み込みする。
その後読み込みを押すと先ほど入力した文字が再度表示されます。
「」タグ内の解説
<body> <input type="text" id="input0" value=""><br> <input type="text" id="input1" value=""><br> <input type="button" onClick="save();" value="保存"> <input type="button" onClick="load();" value="読み込み"><br> </body>
①保存ボタンをクリックすると「save」関数を呼び出す
②読み込みボタンをクリックすると「load」関数を呼び出す
③「id」の値が「input0」「input1」の入力欄に文字列を書き込む。
④「保存ボタン」をクリックして値を保存。
⑤「読み込みボタン」をクリックするとそれぞれの入力欄に値を読み込む。
function save() { // 『input0』『input1』要素の値を取得して、クッキーに書き込み writeCookie("input0", document.getElementById("input0").value, 1); writeCookie("input1", document.getElementById("input1").value, 1); } function load() { // クッキーから読み込んだ値を、『input0』『input1』要素に設定 document.getElementById("input0").value = readCookie("input0"); document.getElementById("input1").value = readCookie("input1"); }
「save」と「load」関数では以下の関数を使いました。
・「writeCookie」
・「readCookie」
この2つの関数を使い「input0」「input1」の「value」の値を読み書きしています。
「input0」と「input1」の要素取得には「document.getElementById」メソッドを使っています。
「writeCookie」関数の解説
function writeCookie(key, value, hours) { if (key == "") return; // 現在時刻に、引数『hours』を加えた時間を作成 var d = new Date(); d.setHours(d.getHours() + hours * 1); // 作成した時間を、設定として配列に格納 var options = new Array(); options.push("expires=" + d.toGMTString()); // 引数『key』『value』を元にした設定と、時刻の設定を、 // 文字列結合してクッキーに書き込み document.cookie = escape(key) + "=" + escape(value) + "; " + options.join("; "); // 『key=value; expires=時間』を書き込み }
「“expires =”+ d.toGMTString()」と時間の文字列を設定しているところはデータの有効期限を表しています。
「save」関数では「writeCookie(key, value,” 1″)」となっており、「hours」の値を「1」として呼び出しています。
つまり有効期限は現在の時刻の1時間後となります。
最後に「document.cookie」に値を設定しています。
この時「key」と「value」の値をエスケープしています。
<エスケープする理由>
「クッキー」に保存できる文字列はURLに利用できる文字列なので、URLに設定できない記号や日本語はエスケープ処理をしてやらなくてはいけない。
「readCookie」関数の解説
「クッキー」からの値の読み込みについて確認します。
まずはプログラムの確認です。
function readCookie(key) { if (key == "") return; // クッキーの文字列『key1=value; key2=value; …』から、 // 引数の『key』を元に、正規表現で値を検索 var re = new RegExp(escape(key) + "=(.*?)(?:;|$)"); if (document.cookie.match(re)) return unescape(RegExp.$1); return ""; }
ここで出てくるのが以前学んだ「正規表現」です。
こちらを使って引数の「key」から対応する値を取得しようとしています。
「RegExp(escape(key) + “=(.*?)(?:;|$)”)」の意味は?→
「エスケープ処理した「key」の値」+「最短一致の任意の文字列」+「「;」または「末尾」(ただしこの文字は含まない)」
次の行の処理はこのようになっています。
①「document.cookie」の文字列を「match」メソッドを使い検索実施。
②この際の引数は正規表現の変数「re」
③検索に一致する値が見つかった場合(戻り値がtrueの場合)
④「if」文の右側を実施
⑤「if」文の右側では「RegExp.$1」という値をアンエスケープしている。
(アンエスケープとはエスケープした文字を元に戻す処理。)
⑥「RegExp.$1」は検索文字列の中で、最初の「(〜)」内の文字列。
(ここでは「key=〜」の「〜」の部分。)
⑦こうして取得した値を「return」を使い「readCookie」関数の戻り値として戻す。
「escape」「unescape」とは
「escape」関数で行われるエスケープ処理
URLに利用できない記号や日本語を特殊な符号で書き換えるもの。
「unescape」関数で行われる処理
エスケープ処理された文字列を、元の文字列に復号するもの。
この2つの関数は「クッキー」のデータ保存以外でも使われます。
例)リンクのURLを利用して、サーバーにデータ送信する際など。
var str = escape("あいう"); document.write(str + "<br>"); str = unescape(str); document.write(str + "<br>");
%u3042%u3044%u3046
あいう
①「escape」関数を使うことで文字列が「%u3042%u3044%u3046」という形式に変換される。
②「unescape」関数を使うことでエスケープされた文字列が「あいう」と復号される。
サーバー上のWebページの「クッキー」
キー | 説明 |
expires | 有効期限 |
domain | クッキーがサーバーに送られるURLのドメイン 省略時は、Webページが保存されているサイトのドメイン 例:「http://www.google.com/hoge/hoge/index.cgi」の場合は「”’www.google.com”’」 |
path | クッキーがサーバーに送られるパス 省略時は現在パス 例:「http://www.google.com/hoge/hoge/index.cgi」の場合は「”’/hoge/hoge/”’」 |
secure | https://の安全なサイトのみにクッキーを送信するフラグ キーの身で値はなし |
document.cookie = "key1=value1; expires=Thu, 22 Apr 2010 09:00:26 UTC; domain=www.google.com; path=/hoge/hoge/; secure";
上記のように書きます。
①WebブラウザはWebページを読み込んだ際にサーバーの要求に従って「クッキー」をサーバーに送信する。
②サーバーからの指示があればデータを「クッキー」に書き込む
サーバーではこの値を見ることで、訪問者が誰かを判断して処理を分析します。
コラム js-cookieの利用
「cookie」を手軽に扱うためのライブラリで「js-cookie」というものがあります。
ファイルのダウンロードはこちらから
CDN経由の場合
<script src="https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js"></script>
js-cookieの利用
まずは「js-cookie」を外部ファイルとして読み込みます。
<script src="js.cookie.js"></script>
基本的な使い方をみていきましょう。
【クッキーの設定】
// cookieの設定 - 現在のサイト Cookies.set('name', 'value'); // cookieの設定 - 期限7日、現在のサイト Cookies.set('name', 'value', { expires: 7 }); // cookieの設定 - 期限7日、パス''(現在のページ) Cookies.set('name', 'value', { expires: 7, path: '' });
【cookieの読み取り】
// cookieの読み取り Cookies.get('name'); // 戻り値として「'value'」の文字列が得られる Cookies.get('nothing'); // 未定義なので戻り値は「undefined」になる // cookieの読み取り - 全て Cookies.get(); // 戻り値として「{ name: 'value' }」のオブジェクトが得られる
【cookieの削除】
// cookieの削除 Cookies.remove('name'); // 現在のページにパスが設定されている場合は注意 Cookies.set('name', 'value', { path: '' }); Cookies.remove('name'); // 失敗する Cookies.remove('name', { path: '' }); // きちんと削除できる
マンガJavaScript第21話 コラム まとめ
ここまで学んだことをまとめます
cookieについて
利用/保存方法
「writecookie」「readcookie」
「escape」「unescape」
cookie のライブラリ「js-cookie」
Twitterフロントエンジニア(@terrace_tech)のフォローは👇