JavaScript アドバンス

JavaScript Cookies

1. クッキー(Cookies)とは?

クッキー(Cookies)を使用すると、ウェブページにユーザー情報を保存することができます。

クッキーは、コンピュータ上の小さなテキストファイルに保存されるデータです。
ウェブサーバーがブラウザにウェブページを送信した後、接続は切断され、サーバーはユーザーに関する情報をすべて「忘れて」しまいます。
クッキーは、「ユーザー情報をいかに記憶するか」という問題を解決するために考案されました。

  • ユーザーがウェブページを訪れたとき、その名前などをクッキーに保存できます。
  • 次回ユーザーがそのページを訪れたとき、クッキーがその名前を「思い出し」ます。

クッキーは、以下のような名前と値のペア(name-value pairs)として保存されます。

username = John Doe

ブラウザがサーバーにウェブページをリクエストすると、そのページに属するクッキーがリクエストに追加されます。これにより、サーバーはユーザー情報を「思い出す」ために必要なデータを取得できます。

※ブラウザでローカルクッキーのサポートが無効になっている場合、以下の例は動作しません。

2. JavaScriptでクッキーを作成する

JavaScriptでは、document.cookie プロパティを使用してクッキーの作成、読み取り、削除を行うことができます。

JavaScriptでクッキーを作成する例:

document.cookie = "username=John Doe";

また、有効期限(UTC時間)を追加することもできます。デフォルトでは、ブラウザを閉じるとクッキーは削除されます。

document.cookie = "username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC";

path パラメータを使用すると、クッキーが属するパスをブラウザに伝えることができます。デフォルトでは、クッキーは現在のページに属します。

document.cookie = "username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC; path=/";

3. JavaScriptでクッキーを読み取る

JavaScriptでクッキーを読み取るには、次のように記述します。

let x = document.cookie;

document.cookie は、cookie1=value; cookie2=value; cookie3=value; のような形式で、すべてのクッキーを1つの文字列として返します。

4. JavaScriptでクッキーを変更する

JavaScriptでクッキーを変更する方法は、作成時と同じです。

document.cookie = "username=John Smith; expires=Thu, 18 Dec 2013 12:00:00 UTC; path=/";

これにより、古いクッキーが上書きされます。

5. JavaScriptでクッキーを削除する

クッキーの削除は非常に簡単です。削除時にはクッキーの値を指定する必要はありません。
単に expires パラメータに過去の日付を設定するだけです。

document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";

       注意: 正しいクッキーを確実に削除するために、クッキーの path を定義する必要があります。一部のブラウザでは、パスを指定しないとクッキーを削除できない場合があります。

6. クッキー文字列の特質

document.cookie プロパティは通常のテキスト文字列のように見えますが、実際は異なります。

document.cookie にクッキー文字列全体を書き込んだとしても、再度読み出したときには、その名前と値のペアしか確認できません。
新しいクッキーをセットしても、古いクッキーは上書きされずに追加されます。そのため、再び document.cookie を読み出すと、以下のような形式でデータを取得することになります。

cookie1 = value; cookie2 = value;

特定のクッキーの値を見つけたい場合は、クッキー文字列内からその値を検索するJavaScript関数を作成する必要があります。

7. JavaScript クッキーの実装例

以下の例では、訪問者の名前を保存するクッキーを作成します。
訪問者が初めてウェブページにアクセスした際、名前の入力を求め、その名前をクッキーに保存します。次回同じページにアクセスした際には、ウェルカムメッセージを表示します。

この例のために、3つのJavaScript関数を作成します。

  1. クッキーの値をセットする関数
  2. クッキーの値を取得する関数
  3. クッキーの値をチェックする関数

7.1 クッキーをセットする関数 (setCookie)

まず、訪問者の名前をクッキー変数に保存する関数を作成します。

function setCookie(cname, cvalue, exdays) {
  const d = new Date();
  // 有効期限をミリ秒に変換して計算
  d.setTime(d.getTime() + (exdays*24*60*60*1000));
  let expires = "expires="+ d.toUTCString();
  // クッキー名、値、有効期限、パスを結合してセット
  document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}

解説:

  • 関数のパラメータは、クッキー名 (cname)、クッキーの値 (cvalue)、および有効期限が切れるまでの日数 (exdays) です。
  • この関数は、クッキー名、クッキーの値、および有効期限の文字列を連結してクッキーをセットします。

7.2 クッキーを取得する関数 (getCookie)

次に、指定したクッキーの値を返す関数を作成します。

function getCookie(cname) {
  let name = cname + "=";
  // 特殊文字を処理するためにクッキー文字列をデコード
  let decodedCookie = decodeURIComponent(document.cookie);
  // セミコロンで分割して配列に格納
  let ca = decodedCookie.split(';');
  for(let i = 0; i <ca.length; i++) {
    let c = ca[i];
    // 先頭の空白を削除
    while (c.charAt(0) == ' ') {
      c = c.substring(1);
    }
    // 指定した名前のクッキーが見つかった場合
    if (c.indexOf(name) == 0) {
      return c.substring(name.length, c.length);
    }
  }
  return "";
}

解説:

  • クッキー名 (cname) をパラメータとして受け取ります。
  • 検索するテキスト用の変数 (name) を作成します (cname + "=")。
  • 特殊文字(例:'$')を含むクッキーを処理するため、クッキー文字列をデコードします。
  • document.cookie をセミコロンで分割し、ca という配列を作成します。
  • 配列をループし、各値 c を読み取ります。
  • クッキーが見つかった場合 (c.indexOf(name) == 0)、その値を返します。見つからない場合は空文字 "" を返します。

7.3 クッキーを確認する関数 (checkCookie)

最後に、クッキーがセットされているかを確認する関数を作成します。
クッキーがセットされている場合は挨拶を表示し、セットされていない場合はプロンプトボックスを表示してユーザー名の入力を求め、setCookie 関数を呼び出してユーザー名クッキーを365日間保存します。

function checkCookie() {
  let username = getCookie("username");
  if (username != "") {
   alert("おかえりなさい、" + username + " さん");
  } else {
    username = prompt("お名前を入力してください:", "");
    if (username != "" && username != null) {
      setCookie("username", username, 365);
    }
  }
}

8. 実装コードの全容

すべての関数を統合したコードは以下の通りです。

// クッキーをセットする関数
function setCookie(cname, cvalue, exdays) {
  const d = new Date();
  d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
  let expires = "expires="+d.toUTCString();
  document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}

// クッキーを取得する関数
function getCookie(cname) {
  let name = cname + "=";
  let ca = document.cookie.split(';');
  for(let i = 0; i < ca.length; i++) {
    let c = ca[i];
    while (c.charAt(0) == ' ') {
      c = c.substring(1);
    }
    if (c.indexOf(name) == 0) {
      return c.substring(name.length, c.length);
    }
  }
  return "";
}

// クッキーを確認・作成する関数
function checkCookie() {
  let user = getCookie("username");
  if (user != "") {
    alert("おかえりなさい、" + user + " さん");
  } else {
    user = prompt("お名前を入力してください:", "");
    if (user != "" && user != null) {
      setCookie("username", user, 365);
    }
  }
}

上記の例では、ページロード時に checkCookie() 関数を実行することで、ユーザーの状態に応じた処理を行うことができます。