こんにちは、かつコーチです。
前回はLocalStorage・SessionStorageの使い方を解説しました。
今回はもう一つのブラウザ保存手段である「Cookie」を扱います。
Cookieは古くからある仕組みですが、LocalStorageと違って「サーバーとのやり取り」を前提に設計されているため、扱い方にコツが必要です。
ログイン状態の保持やアクセス解析など、実務でもよく登場するので、ここでしっかり理解しておきましょう。
Cookieとは?
サーバーとやり取りされる小さなデータ
Cookieは、Webサイトがブラウザに保存させる小さなテキストデータです。
一度保存されると、同じサイトへのリクエストのたびに、ブラウザが自動的にサーバーへ送信してくれます。
この「リクエストのたびに自動送信される」という性質が、LocalStorage・SessionStorageとの決定的な違いです。
LocalStorageとの違いを整理する
前回学んだLocalStorageと比較すると、それぞれの得意分野が見えてきます。
| 項目 | Cookie | LocalStorage |
|---|---|---|
| サーバーへの自動送信 | される(リクエストのたびに送信) | されない |
| 保存容量の目安 | 4KB程度 | 5MB程度 |
| 有効期限の指定 | 細かく指定できる | 明示的に削除するまで残る |
| 主な用途 | ログインセッション管理、認証トークン | 設定値、下書きデータなどの一時保存 |
「サーバー側でも参照する必要があるデータはCookie」「ブラウザ側だけで完結するデータはLocalStorage」と覚えておくと、使い分けに迷いにくくなります。
私が新人の頃、ログイン状態の判定をすべてLocalStorageだけで実装しようとして、サーバー側のセッション管理と状態がずれてしまい、ログアウトしたはずなのに画面上だけログイン状態のままになる不具合を出したことがあります。
サーバーと連携する必要がある情報は、素直にCookieを使うべきだったと反省したのを覚えています。
document.cookieでCookieを操作する
Cookieを設定する基本の書き方
JavaScriptからCookieを扱う場合、document.cookie というプロパティを使います。
// 基本の書き方:key=value 形式の文字列を代入する
document.cookie = "username=katsucoach";
一見すると単純な代入に見えますが、document.cookie は少し特殊なプロパティで、代入すると既存のCookieに追加される挙動になります(上書きされるわけではありません)。
有効期限・パスなどのオプションを指定する
実務では、有効期限を指定しないCookieはブラウザを閉じると消えてしまいます。
有効期限などのオプションは、セミコロン区切りで追加します。
// 7日後に期限切れになるCookieを設定する
const date = new Date();
date.setDate(date.getDate() + 7);
document.cookie = `username=katsucoach; expires=${date.toUTCString()}; path=/`;
主なオプションを整理しておきます。
| オプション | 役割 |
|---|---|
expires | 有効期限(GMT形式の日時文字列) |
max-age | 有効期限を秒数で指定(こちらの方が扱いやすい) |
path | Cookieが有効なパスの範囲(/ はサイト全体) |
secure | HTTPS通信時のみ送信する |
samesite | 他サイトからのリクエスト時にCookieを送るかの制御 |
expires より max-age の方が直感的に書けるので、私は普段こちらを使うことが多いです。
// max-ageで7日後(60秒 × 60分 × 24時間 × 7日)に期限切れにする
document.cookie = "username=katsucoach; max-age=" + 60 * 60 * 24 * 7 + "; path=/";
Cookieを読み取る
document.cookie から値を読み取ると、すべてのCookieが key=value; key2=value2 の形式で1つの文字列として返ってきます。
console.log(document.cookie);
// "username=katsucoach; theme=dark; sessionId=abc123"
これでは特定のキーの値だけを取り出すのが面倒なので、次のような関数を用意しておくと便利です。
function getCookie(name) {
const cookies = document.cookie.split("; ");
for (const cookie of cookies) {
const [key, value] = cookie.split("=");
if (key === name) {
return decodeURIComponent(value);
}
}
return null;
}
console.log(getCookie("username")); // "katsucoach"
console.log(getCookie("notExist")); // null
つまずきやすいポイント
文字列連結でCookieを組み立てるとバグりやすい
Cookieの値に日本語や特殊文字を含める場合、エンコードを忘れると意図しない挙動になります。
❌ Before:エンコードせずにそのまま設定する
const displayName = "かつコーチ";
// 日本語や記号をそのまま埋め込んでしまう
document.cookie = `displayName=${displayName}; path=/`;
console.log(document.cookie);
// ブラウザによっては文字化けしたり、値の一部が欠けたりすることがある
Cookieの値には本来使えない文字(スペースやセミコロンなど)が含まれる可能性があり、日本語もそのまま入れると環境によって挙動が不安定になります。
私はこれが原因で、開発環境では正常に見えていたCookieが、別のブラウザで確認したときだけ値が途中で切れてしまうという不具合に遭遇したことがあります。
✅ After:encodeURIComponentでエンコードしてから設定する
const displayName = "かつコーチ";
// 値をエンコードしてから設定する
document.cookie = `displayName=${encodeURIComponent(displayName)}; path=/`;
// 読み取るときはdecodeURIComponentでデコードする
function getCookie(name) {
const cookies = document.cookie.split("; ");
for (const cookie of cookies) {
const [key, value] = cookie.split("=");
if (key === name) {
return decodeURIComponent(value);
}
}
return null;
}
console.log(getCookie("displayName")); // "かつコーチ"
encodeURIComponent / decodeURIComponent をセットで使うことで、日本語や記号を含む値でも安全に保存・取得できます。
Cookieを削除する方法
Cookieには専用の削除メソッドが存在しません。
削除したい場合は、有効期限を過去の日時にして上書きするというテクニックを使います。
function deleteCookie(name) {
// max-ageを0以下にすることで即座に無効化する
document.cookie = `${name}=; max-age=0; path=/`;
}
deleteCookie("username");
console.log(getCookie("username")); // null
path の指定が設定時と異なると削除に失敗するので、削除するときは設定したときと同じ path を指定するのがポイントです。
HttpOnly Cookieは操作できない
JavaScriptから見えないCookieがある
ここは中級者向けに知っておいてほしい重要なポイントです。
サーバー側が Set-Cookie ヘッダーに HttpOnly 属性をつけて発行したCookieは、document.cookie から一切参照できません。
// HttpOnly属性がついたCookie(例:セッションID)は
// document.cookieの出力に一切含まれない
console.log(document.cookie);
// "theme=dark" のようにHttpOnlyでないものだけが表示される
これはセキュリティ上の仕様で、XSS(クロスサイトスクリプティング)攻撃によって悪意あるスクリプトがセッションIDなどの重要な情報を盗み出すのを防ぐための仕組みです。
「サーバー側でCookieを設定したのに、JavaScriptから値が取れない」と困ったときは、まずこの HttpOnly 属性が原因でないか確認してみてください。
ログイン認証のトークンなど、セキュリティ上重要な情報は、そもそもJavaScriptから触れないHttpOnly Cookieで管理するのが望ましい設計です。
まとめ
この記事のポイント
- Cookieはリクエストのたびにサーバーへ自動送信される点がLocalStorageと異なる
document.cookieへの代入で設定し、max-ageやpathなどのオプションを付与する- 日本語や記号を含む値は
encodeURIComponent/decodeURIComponentで安全に扱う - 削除専用のメソッドはなく、有効期限を過去にして上書きすることで削除する
HttpOnly属性付きCookieはセキュリティ上、JavaScriptから参照できない
次に読むべき記事
次回は、日付や時刻を扱う基本の道具である「Dateオブジェクト」の使い方を解説していきます。
Cookieの有効期限計算でも登場した Date について、より詳しく見ていきましょう。
→ 次の記事:Dateオブジェクトで日付・時刻を扱う