doc drawn up: 2002-12-21 .. 2003-04-09

Cookie に関する覚え書き

歴史的経緯

Cookie 技術は、元々は Netscape が、自社製品のブラウザとサーバ間の情報のやりとりにおいて HTTP 通信を拡張した情報のやりとりができるように、独自に開発した規格である。

Netscape Navigator がデファクト・スタンダート化し、Netscape 規格の Cookie 技術も広く普及してしまった。Netscape が自社製品同士の例外的な機能として Cookie 技術を用いる分には支障がないが、一般的な技術として Web 空間上で用いられるようになると、Web 空間上の特に HTTP プロトコルなどの技術と抵触しない規格として公的に改めて制定する必要がある。そのような要求から Netscape 規格に基づき、Web 規格としての問題を解消する形で新しく策定されたのが RFC 2109 である(この RFC 2109 はすでに陳腐化し、改訂されて RFC 2965 になっている)。

理論的には(合法思想では)、RFC に準拠することが過ちのない完全な正当だが、一方で現実的には Netscape の既存規格にしかブラウザが依然として対応していないので、Netscape 規格でしか実装のしようがないという現状がある。しかし、改訂された RFC 2965 では、Netscape の Set-Cookie HTTP ヘッダに対して、全く別種の新しい HTTP ヘッダとして Set-Cookie2 ヘッダを提案しているので、全く共存が可能である。つまり、Netscape 規格の Set-Cookie ヘッダと、RFC2965 の Set-Cookie2 ヘッダを併用すれば理論的にも実際的にも要求を満たすことができるという結論になる。
(※RFC 2109 の情報は Netscape 規格そのものを置き換えようとするものなので却って混乱する。排除して考えるのが正解でありそれが RFC 2965 への改訂理由ともなっている)

Netscape 規格と RFC 2965 規格の違いの実際

Set-Cookie: NAME=VALUE; expires=Sun, DD-MMM-YYYY hh:mm:ss GMT
Set-Cookie2: NAME="VALUE"; Version="1"; Max-Age="XXXX"

右側の値の記述方法が、ダブルクォートで囲うようになっている点、Version が必須になっている点、有効期限が日時ではなく秒単位のタイマーとなっている点が主な違いである。

実際上は、この 2 つの HTTP ヘッダを併記し、Set-Cookie2 の普及のタイミングを見てシフトしていくという姿勢で臨むのが正解だろう。現状では、Set-Cookie2 の HTTP ヘッダの行はコメントアウトしても差し支えない。

利用方法

Cookie は記録時にその有効期限と、対象サイト URI(パス)を特定する。有効期限が切れておらず、対象サイト URI に相当するサーバと接続した場合、クッキーに記録した情報をサーバに対して(サーバからの要求のあるなしに関わらず)自動的に送信する。

送信した Cookie 情報を利用するかしないかは、サーバ側の CGI プログラム次第である。環境変数 HTTP_COOKIE に格納されているので、その値を CGI プログラムで扱う。

Cookie 記録時と利用時に必要となるのは、URI エンコードと URI デコードである。クッキーの情報は HTTP ヘッダとして HTTP 通信において受け渡しされるので、当然の事ながら、HTTP 規格に準じたデータ形式に変換されている必要がある。つまり URI エスケープ済みのデータということになるわけである(ここでは URI エスケープについては詳しくは述べない)。そしてその URI エンコードされたデータを取り出す時には、URI デコードする必要が生じる。

サーバサイドの Perl/CGI によって URI エンコード/デコードする場合には、何の問題もないが、クライアントサイドで JavaScript を利用して URI エンコード/デコードする場合には、注意が必要である。常套手段とされている、escape, unescape は文字化けしてしまう可能性があるので、使えない。JavaScript 1.5 以上(JScript 5.5 以上)で採用されている、encodeURI, decodeURI, encodeURIComponent, decodeURIComponent などの新しい命令セットを利用する必要がある。

ちなみに、JavaScript 1.5 に対応しているのは、IE は 5.5 以上、NN は 6.0 以上だが、NN 6 は少なくとも decodeURIComponent にバグ(ある程度大きなデータをデコードしようとするとエラーになる)があるので 7.0 以上が望ましい。


参考


《以上》