Cookie を検出してブロックする、のではなくて あるサイトに訪れたユーザの ブラウザが Cookie をブロックする設定となっているのを検出できるかどうか、 のおはなし。

プライバシーとセキュリティ→Cookie→Cookieを受け入れる
Android のブラウザだと「Cookieを受け入れる」で Cookie のブロックを指定できる
navigator.cookieEnabledを見ればいいだけの簡単なお仕事だった(ドメイン指定の設定も反映される)。 なので、この記事の内容は忘れるように。

Solution

document.cookie = "cookie-block-check=a;max-age=1;domain=%DOMAIN%;path=%PATH%%SECURE%"
                  .replace("%DOMAIN%", location.host)
                  .replace("%PATH%", location.pathname)
                  .replace("%SECURE%", (location.protocol == "https:")? ";secure" : "")
if (document.cookie == "") {
    alert("Cookie is blocked");
} else {
    alert("Cookie is allowed");
}

Cookie の受け入れをON/OFFするなり、ドメイン指定で拒否/許可を切り替えるなりして、 下記ボタンを押すと動作が変わると思う。

仕組み

話は単純で、Cookie を実際に JavaScript でつくってして、それが登録されているかを見えればよい

なお、この Cookie の扱いは下記の通り慎重を期している。

  • max-age=1 とすることで賞味期限を1秒としている。
    • ここで設定した cookie-block-check=a は HTTP request 等に含めるまでもないものである。
    • if (document.cookie == "") の判定後は不要である。
    • 明示的に消去してもよいがだるいので、期限を設けてブラウザに自動削除させている。
  • すぐに消えるとはいえ、念の為 domain path secure attribute を付けるなど 安全性には気をつけた

「一時的に許可」の判定はできないし、意味はない

JavaScript の document.cookie で cookie を取得するときには、 key=value ペアしか取得できないので、 「一時的に許可(ブラウザ閉じたら削除)」になっているかは判定できない。

もっとも、cookie はユーザによって後で削除されるかもしれないし、 ブラウザによって(cookie の格納個数などの原因によって)削除されるかもしれない。 これは原理的に判断できるわけがないので、 一時的に許可されているか=後で削除されるかどうかを判定するのはできないし、無意味だ。

参考文献

  • "HTTP State Management Mechanism", RFC 6265, April 2011
    • 特に 7.2 節に User-Agent が勝手に Cookie を削除する云々の話がある
  • "document.cookie - DOM", MDN