とほほのCookie入門

目次

Cookieの概要

Cookie とは、以下のようなことを実現するための機構です。

下記の仕様書が公開されています。

上記のようなデータは CGI などを用いてサーバー側に記録することもできますが、Cookie を用いることにより、クライアント側(ブラウザを起動する側)のハードディスク内に Cookie情報 と呼ばれるデータを記録することができるようになります。

Cookie情報が保存されるファイル

Cookie情報が保存されるファイルは OS やブラウザのバージョンによって異なりますが、例えば以下のようなフォルダやファイルに記録されます。

Cookieの実行例

Cookie の実行例を次に示します。「再表示」を行うと、これまでの訪問回数と前回の訪問日が表示されます。オフラインでは動作しません。オンラインで実行してください。

一度ページを表示すると Cookie情報がハードディスク内に書き込まれ、再度そのページにアクセスした際に Cookie情報がサーバーに送られます。

Cookieの設定

Cookie を受け付けるか受け付けないかの設定は以下のメニューで行います。

ブラウザメニュー
IE6.0[ツール]→[インターネットオプション]→[プライバシー]
IE5.0[ツール]→[インターネットオプション]→[セキュリティ]→[レベルのカスタマイズ]→[Cookie]
NS6.*[編集]→[設定]→[プライバシーとセキュリティ]→[Cookie]
NS4.*[編集]→[設定]→[詳細]→[Cookie]

Cookieの書き込み

JavaScript を用いて Cookie を設定する場合は次のようにします。

JavaScript
document.cookie = "~";

CGI(Perl) を用いる場合は次のようにします。

Perl
print "Content-type: text/html\n";
print "Set-Cookie: ~\n";
print "\n";

HTML で指定するには次のようにします。ただし、この方法は推奨されない方式となりました。。

HTML
<meta http-equiv="Set-Cookie" content="~">

~の部分には次のような文字列を指定します。

フォーマット
NAME=値; expires=値; domain=値; path=値; secure

NAME=値; 以外は省略可能です。それぞれ、次のような意味があります。

パラメータ 意味
NAME= 必須。好きな名前に好きな値を指定します。セミコロン(;)、カンマ(,)、空白文字( )や日本語を使用する際にはそれぞれ、何らかの形式にエンコードする必要があります。エンコードには %3B、%2C、%20 などの URL形式のエンコードがよく用いられるようです。
expires= クライアント側に記録される Cookie の有効期限を
   Thu, 1-Jan-2030 00:00:00 GMT
のような形式で指定します。タイムゾーンは必ず GMT で指定します。省略するとブラウザを終了させるまでが有効期限となります。過去の値を指定すると Cookie を削除します。
domain= Cookie を発行する Webサーバーの名前を指定します。省略した場合は Webサーバー名(www.tohoho-web.com など)になります。
path= ここで指定したパス名にマッチするページを参照したときに、ブラウザは保存しておいた Cookie情報をサーバーに送ります。例えば、path=/tanaka と指定すると、/tanaka にマッチするすべてのページに対して Cookie情報が送られます。省略時は、Cookie を設定したページのパス名部になります。
secure これを記述しておくと、サーバーとの接続がセキュアである時のみ、Cookie情報が送信されるようになります。

Cookie書き込みの例

最も簡単な書き込みの例は次のようになります。これは、ブラウザが終了するまで有効で、設定したページと同じフォルダにある(もしくは下位層にある)ページに送信されます。

HTTP Header
Set-Cookie: NAME=tanaka;

有効期限を指定すると次のようになります。ブラウザを終了しても、OS を再起動しても、有効期限までディスクに保存されています。

HTTP Header
Set-Cookie: NAME=tanaka; Tue, 31-Dec-2030 23:59:59;

Cookieの読み込み

JavaScriptを用いてCookieの値を読みこむには、document.cookie の値を参照します。解釈方法は上記のサンプルコードを参照してください。

JavaScript
alert(document.cookie);

CGI(Perl)でCookieの値を読みこむには、環境変数の HTTP_COOKIE の値を参照します。

Perl
print "$ENV{'HTTP_COOKIE'}\n";

具体的な読み込みの例は、上記の「Cookieの実行例」のソースコードを参照してください。

エンコードとデコード

Cookieの値では、=や;などの特殊記号や日本語文字は %82%A0 のような形式にエンコードして記録しておき、読み出し時にこれをデコードしてやる必要があります。

JavaScriptでエンコードするには次のようにします。最近の IE では日本語を %u65E5 のような Unicode にエンコードしてしまうので注意してください。

JavaScript
xx = escape(xx);

JavaScriptでデコードするには次のようにします。

JavaScript
xx = unescape(xx);

CGI(Perl)でエンコードするには次のようにします。

JavaScript
$xx =~ s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg;

CGI(Perl)でデコードするには次のようにします。

JavaScript
$xx =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C", hex($1))/eg;

Cookieに関するQ&A

Cookieの語源は何ですか?

ブラウザに「食わせるもの」という意味ではないかと想像していたのですが、仕様書によると「Cookieの名前には特に理由は無い。」だそうです。ちょっと残念。

Cookieで複数の値を設定するには?

CGI や <meta> の場合は Set-Cookie ヘッダを複数記述してください。

HTTP Header
Set-Cookie: LOGIN=tanaka;
Set-Cookie: PASSWD=hi.mi.tu;

JavaScript の場合は document.cookie = "~" を複数記述してください。

HTTP Header
document.cookie = "LOGIN=tanaka;";
document.cookie = "PASSWD=hi.mi.tu";

複数の値をひとつの値にまとめてしまう方法もあります。

HTTP Header
Set-Cookie: VALUE=NAME:tanaka:PASSWD:hi.mi.tu;

仕様書には、ひとつの Set-Cookie で複数の値を設定可能と書いてあるのですが、現状のブラウザではうまく動作しないようです。

expires で過去の時刻を指定してください。

HTTP Header
Set-Cookie: NAME=tanaka; expires=Fri, 31-Dec-1999 23:59:59 GMT;

Cookieの有効期限を無期限にするには?

無期限という指定はできないようです。2038年以降の日付をうまく扱えないシステムもあるので、2037年頃の日付を指定しておきましょう。

HTTP Header
Set-Cookie: NAME=tanaka; expires=Tue, 31-Dec-2037 00:00:00 GMT;

path=/ とすると、そのサーバー上のすべてのファイルに対して送信されるの?

はい。共有サーバーで、迂闊に path=/ などとしないようにしましょう。

path=/xxx.htm と指定すると OK かな・・・と思ったのですが、期待通りには動作してくれません。現状はフォルダ単位に設定されるようです。

escape()でエンコードされたUnicodeをCGIでシフトJISにデコードするには?

Jcode.pm というモジュールを使用すると、Unicode → シフトJIS, EUC, JIS などの変換ができるようです。