【JavaScript】Cookie の取得・設定・削除の方法|document.cookie・有効期限・SameSite・セキュリティまで解説

Cookie はブラウザにデータを保存し、同じサイトへのリクエスト時に自動送信される仕組みです。ログイン状態の維持、ユーザー設定の保存、トラッキングなどに使われます。

本記事では、document.cookie による取得・設定・削除有効期限や属性の指定、ヘルパー関数の作成、localStorage との使い分けまで解説します。

この記事でわかること
・document.cookie で Cookie を設定する方法
・Cookie を取得・パースする方法
・有効期限(expires / max-age)の設定
・path / domain / Secure / SameSite 属性の意味
・Cookie を削除する方法
・再利用可能なヘルパー関数の作成
・localStorage / sessionStorage との使い分け
・セキュリティの注意点(HttpOnly / GDPR)
スポンサーリンク

Cookie を設定する

JavaScript(Cookie の設定)
// 基本: key=value を設定
document.cookie = "username=Tanaka";

// 有効期限を設定(expires: UTC 形式の日時)
const date = new Date();
date.setDate(date.getDate() + 7); // 7 日後
document.cookie = `username=Tanaka; expires=${date.toUTCString()}; path=/`;

// max-age で秒数指定(expires より簡潔)
document.cookie = "username=Tanaka; max-age=604800; path=/"; // 7 日 = 604800 秒

// 複数の属性を同時に指定
document.cookie = "theme=dark; max-age=31536000; path=/; Secure; SameSite=Lax";
document.cookie への代入は「追加」であり「上書き」ではない
document.cookie = "a=1" のあとに document.cookie = "b=2" を実行しても、a は消えません。同名のキーを再設定すれば値が更新されますが、異なるキーは追加されます。全 Cookie を一括クリアする方法はありません(1 つずつ削除が必要)。

Cookie の属性一覧

属性 意味
expires 有効期限(UTC 日時文字列) expires=Thu, 06 Apr 2027 00:00:00 GMT
max-age 有効期間(秒数: 推奨) max-age=604800(7 日)
path Cookie が送信されるパス path=/(サイト全体)
domain Cookie が送信されるドメイン domain=.example.com(サブドメイン含む)
Secure HTTPS 接続でのみ送信 Secure
SameSite クロスサイトリクエストでの送信制御 SameSite=Lax / Strict / None
HttpOnly JavaScript からアクセス不可(サーバー側で設定 ―(JS では設定不可)
path=/ を常に指定する
path を省略すると現在のページのパスだけに Cookie が紐づきます。サイト全体で Cookie を使いたい場合は path=/ を必ず指定してください。path が異なると同名でも別の Cookie として扱われます。

Cookie を取得する

JavaScript(document.cookie の取得とパース)
// document.cookie は全 Cookie を 1 つの文字列で返す
console.log(document.cookie);
// "username=Tanaka; theme=dark; lang=ja"

// 特定のキーの値を取得する関数
function getCookie(name) {
  const cookies = document.cookie.split("; ");
  for (const cookie of cookies) {
    const [key, ...valueParts] = cookie.split("=");
    if (key === name) {
      return decodeURIComponent(valueParts.join("="));
    }
  }
  return null; // 見つからない場合
}

console.log(getCookie("username")); // "Tanaka"
console.log(getCookie("missing"));  // null
document.cookie の取得は直感的でない
document.cookie は全 Cookie をセミコロン区切りの 1 文字列で返します。個別のキーで取得する API はないため、文字列をパースする必要があります。後述のヘルパー関数を用意すると便利です。

Cookie を削除する

JavaScript(Cookie の削除)
// max-age=0 で即座に削除
document.cookie = "username=; max-age=0; path=/";

// expires を過去日時に設定しても削除できる
document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
削除時は path を設定時と同じにする
Cookie は path と domain の組み合わせで識別されます。設定時に path=/ で作成した Cookie を削除するには、削除時も path=/ を指定してください。path が異なると削除されません。

再利用可能なヘルパー関数

JavaScript(Cookie ヘルパー関数)
// Cookie を設定する
function setCookie(name, value, days = 365, options = {}) {
  const maxAge = days * 24 * 60 * 60;
  const { path = "/", secure = false, sameSite = "Lax" } = options;
  let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
  cookie += `; max-age=${maxAge}; path=${path}; SameSite=${sameSite}`;
  if (secure) cookie += "; Secure";
  document.cookie = cookie;
}

// Cookie を取得する
function getCookie(name) {
  const match = document.cookie.match(
    new RegExp("(?:^|; )" + name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + "=([^;]*)")
  );
  return match ? decodeURIComponent(match[1]) : null;
}

// Cookie を削除する
function deleteCookie(name, path = "/") {
  document.cookie = `${encodeURIComponent(name)}=; max-age=0; path=${path}`;
}

// 使い方
setCookie("theme", "dark", 30);           // 30 日間保存
console.log(getCookie("theme"));           // "dark"
deleteCookie("theme");                     // 削除
console.log(getCookie("theme"));           // null
encodeURIComponent でエンコードする
Cookie の値に = ; , などの特殊文字が含まれると正しくパースできなくなります。encodeURIComponent でエンコードし、取得時に decodeURIComponent でデコードするのが安全です。

SameSite 属性の詳細

動作 用途
Lax(デフォルト) トップレベルナビゲーション(リンク遷移)ではCookie を送信。フォーム POST / Ajax / iframe では送信しない 一般的なサイトに推奨
Strict クロスサイトからの全リクエストで Cookie を送信しない セキュリティ最優先(銀行サイト等)
None クロスサイトでも Cookie を送信(Secure 必須 サードパーティ Cookie / 埋め込みウィジェット
SameSite=None には Secure が必須
SameSite=None を指定する場合は Secure 属性も必須です(HTTPS のみ)。Secure なしで SameSite=None を設定するとブラウザに無視されます。

Cookie vs localStorage vs sessionStorage

項目 Cookie localStorage sessionStorage
容量 約 4KB / ドメイン 約 5〜10MB 約 5〜10MB
有効期限 指定可能(expires / max-age) 永続(手動削除まで) タブを閉じるまで
サーバー送信 自動送信(毎リクエスト) 送信しない 送信しない
JS アクセス document.cookie localStorage.getItem() sessionStorage.getItem()
HttpOnly 対応 可能(サーバー側で設定) 不可 不可
主な用途 セッション管理・認証・トラッキング ユーザー設定・テーマ・フォーム下書き 一時的なフォームデータ
使い分けの判断基準
・サーバーに自動送信したい(認証トークン等)→ Cookie
・クライアント側だけで使う設定データ → localStorage
・タブを閉じたら消えてよいデータ → sessionStorage
・4KB を超えるデータ → localStorage(Cookie は容量が小さい)

セキュリティの注意点

リスク 対策
XSS で Cookie が盗まれる HttpOnly 属性をサーバー側で設定(JS からアクセス不可にする)
CSRF(クロスサイトリクエスト偽造) SameSite=Lax/Strict + CSRF トークン
通信の盗聴 Secure 属性(HTTPS のみ送信)
クロスサイトトラッキング サードパーティ Cookie の規制(Chrome 2025 年以降段階的廃止)
HttpOnly は JavaScript で設定できない
HttpOnly 属性はサーバー側の Set-Cookie ヘッダーでのみ設定可能です。document.cookie では HttpOnly Cookie の読み取り・設定はできません。認証トークンなど機密情報は必ずサーバー側で HttpOnly を設定してください。

実務パターン集

パターン(1): ダークモードの保存

JavaScript
// テーマ設定を Cookie に保存
function toggleTheme() {
  const current = getCookie("theme") || "light";
  const next = current === "light" ? "dark" : "light";
  setCookie("theme", next, 365);
  document.documentElement.dataset.theme = next;
}

// ページ読み込み時にテーマを適用
const savedTheme = getCookie("theme") || "light";
document.documentElement.dataset.theme = savedTheme;

パターン(2): 初回訪問の判定(バナー表示)

JavaScript
// 初回訪問かどうかを Cookie で判定
if (!getCookie("visited")) {
  // 初回訪問 → ウェルカムバナーを表示
  document.getElementById("welcome-banner").hidden = false;
  setCookie("visited", "true", 30); // 30 日間記憶
}

パターン(3): Cookie 同意バナー(GDPR 対応)

JavaScript
// Cookie 同意がまだなければバナーを表示
if (!getCookie("cookie_consent")) {
  document.getElementById("cookie-banner").hidden = false;
}

// 「同意する」ボタン
document.getElementById("accept-cookies").addEventListener("click", () => {
  setCookie("cookie_consent", "accepted", 365);
  document.getElementById("cookie-banner").hidden = true;
  // 同意後にアナリティクス等を読み込む
  loadAnalytics();
});

パターン(4): 全 Cookie を一覧表示(デバッグ用)

JavaScript
// 全 Cookie をオブジェクトとして取得
function getAllCookies() {
  if (!document.cookie) return {};
  return document.cookie.split("; ").reduce((acc, pair) => {
    const [key, ...val] = pair.split("=");
    acc[decodeURIComponent(key)] = decodeURIComponent(val.join("="));
    return acc;
  }, {});
}

console.table(getAllCookies());

パターン(5): 全 Cookie を削除(ログアウト時)

JavaScript
// 全 Cookie を削除(HttpOnly 以外)
function deleteAllCookies() {
  document.cookie.split("; ").forEach(cookie => {
    const name = cookie.split("=")[0];
    document.cookie = `${name}=; max-age=0; path=/`;
  });
}

よくある質問

QCookie に日本語を保存できますか?
AencodeURIComponent でエンコードすれば保存可能です。取得時は decodeURIComponent でデコードしてください。エンコードしないと文字化けやパースエラーの原因になります。
QCookie の最大サイズは?
A1 つの Cookie は約 4KB(4096 バイト)、1 ドメインあたり約 50〜180 個(ブラウザによる)が上限です。大量のデータを保存する場合は localStorage を使ってください。
Qexpires と max-age はどちらを使うべきですか?
Amax-age を推奨します。秒数で指定するためシンプルで、expires のようにタイムゾーンの問題がありません。max-age=0 で即座に削除、max-age=604800 で 7 日間保持です。
QCookie を設定したのに取得できません
A主な原因: (1) path が異なる(設定時と取得時で path が違うと見えない)。(2) HttpOnly 属性が付いている(サーバー設定の Cookie は JS で読めない)。(3) Secure 属性で HTTP 環境では送信されない。
Qサードパーティ Cookie はいつ廃止されますか?
AChrome は 2025 年以降、段階的にサードパーティ Cookie のサポートを制限する予定です。Firefox と Safari は既にデフォルトでブロックしています。トラッキング目的の Cookie に依存している場合は、Privacy Sandbox やファーストパーティデータへの移行を検討してください。
QCookie と localStorage はどちらが安全ですか?
AXSS 攻撃に対しては Cookie + HttpOnly が安全です(JavaScript からアクセスできないため)。localStorage は JavaScript から自由に読み書きできるため、XSS でトークンが盗まれるリスクがあります。認証トークンは HttpOnly Cookie に保存し、ユーザー設定は localStorage に保存するのが一般的です。

まとめ

JavaScript での Cookie 操作の要点をまとめます。

やりたいこと 方法
Cookie を設定 document.cookie = “key=value; max-age=秒; path=/”
Cookie を取得 document.cookie をパース(ヘルパー関数推奨)
Cookie を削除 document.cookie = “key=; max-age=0; path=/”
有効期限を設定 max-age=604800(7 日)/ expires=UTC 日時
HTTPS のみ送信 Secure 属性を追加
CSRF 対策 SameSite=Lax(デフォルト)/ Strict
サーバーに送信しないデータ localStorage / sessionStorage を使う
認証トークンの保存 サーバー側で HttpOnly Cookie として設定