cookie とは、ブラウザ側に個人情報を保存する仕組みです。 ある web 掲示板にメッセージを書き込んだとします。 そこで自分の名前とメールアドレスを入力します。 しかし、再び訪問したときに、以前に入力した名前やメールアドレスを 再度入力するのは面倒です。そういう場合に cookie を使います。cookie はもともと Netscape 社が提唱したものです。 もともと cookie の仕様は、Netscape が公開している 仕様書 に記載されていました。これは Set-Cookie と Cookie というヘッダを使用するものでした。その後、Netscape の仕様を追認・補完する形で RFC 2109 が公開されました。 その後、RFC 2965 で Set-Cookie2 と Cookie2 という新たな仕組みが提案されました。RFC 2965 は RFC 2109 を obsolete しているので、これに従うのであれば Set-Cookie・Cookie の使用はやめて、Set-Cookie2 と Cookie2 に移行すべきです。 ただし、理由は知りませんが、RFC 2965 方式の Set-Cookie2 と Cookie2 は人気がありません。 世の中の大半のブラウザ・web サーバは、Set-Cookie・Cookie 方式にしか対応していないと思われます。2005年 6月現在、少なくとも Mozilla と IE は Set-Cookie2 と Cookie2 に未対応で、Opera は対応済のようです。
よって、Cookie を利用する側としては、Set-Cookie・Cookie だけ知っておけば十分でしょう。
cookie とは、CGI プログラム側がブラウザに渡すデータです。 データを渡される側のブラウザは、どこの誰から受け取ったものかを記録し、 受け取ったデータを保存しておきます。 次回同じ URL にアクセスした場合は、ブラウザが WWW サーバに前回受け取った データを提出します。 ただし、WWW サーバが渡した cookie データをブラウザが受け取るかどうかは ブラウザの勝手です。次回のアクセス時にブラウザが WWW サーバに cookie データを 提出するかもブラウザの勝手です。
cookie というのは、ただの文字列でしかありません。 そのデータをどう解釈するかは、cookie を解釈する CGI プログラム次第です。
cookie をセットする場合は、Set-Cookie: ヘッダを出力します。1: #!/usr/local/bin/perl 2: 3: print <<'END'; 4: Content-type: text/html; charset=EUC-JP 5: Set-Cookie: DATA=abc; expires=Mon, 30 Dec 2020 23:59:59 GMT 6: 7: <HTML><BODY BGCOLOR=WHITE> 8: <TT>Set-Cookie: DATA=abc; expires=Mon, 30 Dec 2020 23:59:59 GMT 9: </TT> 10: <BR> 11: というデータをヘッダに出力しました。 12: </BODY></HTML> 13: ENDこの CGI プログラムを実行すると、ブラウザの設定によってはという確認ダイアログが出ます。ここで「確認」を押すと cookie を受け入れますが、「キャンセル」を押すと 渡された cookie データを記憶しません。5: Set-Cookie: DATA=abc; expires=Mon, 30 Dec 2020 23:59:59 GMTここでは、DATA=ABC という cookie データをセットしています。 最後に ; を付けることで、項目の終わりを表します。 次の expires は、この cookie データの有効期限を表します。 この cookie は世界標準時 (GMT) で「2020年12月30日 (月) 23:59:59」 で期限切れとなります。期限切れかどうかを判断するのはブラウザ側です。 次回アクセス時に、ブラウザはという動作をします。
- 期限内なら cookie データを WWW サーバに提出
- 期限切れなら cookie データを破棄 (WWW サーバに提出しない)
今度は cookie の取得です。まず、上の CGI にアクセスし、 cookie を受け取らないと何も表示されません。1: #!/usr/local/bin/perl 2: 3: if ( $ENV{HTTP_COOKIE} ne '' ){ 4: foreach ( split(/\s*;\s*/,$ENV{HTTP_COOKIE}) ){ 5: foreach ( split(/\,/,$_) ){ 6: my ($key,$value) = split(/=/,$_); 7: $value =~ tr/+/ /; 8: $value =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg; 9: $COOKIE{$key} = $value; 10: } 11: } 12: } 13: 14: print <<END; 15: Content-type: text/html; charset=EUC-JP 16: 17: <HTML><BODY BGCOLOR=WHITE> 18: \$ENV{HTTP_COOKIE} = $ENV{HTTP_COOKIE} 19: <P> 20: END 21: 22: foreach ( sort keys %COOKIE ){ 23: print "$_ = $COOKIE{$_}<BR>\n"; 24: } 25: 26: print "</BODY></HTML>\n";$ENV{HTTP_COOKIE}
1: #!/usr/local/bin/perl 2: 3: print "Content-type: text/html; charset=EUC-JP\n"; 4: 5: if ( $ENV{HTTP_COOKIE} ne '' ){ 6: foreach ( split(/\s*;\s*/,$ENV{HTTP_COOKIE}) ){ 7: foreach ( split(/\,/,$_) ){ 8: ($key,$value) = split(/=/,$_); 9: $value =~ tr/+/ /; 10: $value =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg; 11: $COOKIE{$key} = $value; 12: } 13: } 14: } 15: 16: read(STDIN,$buf,$ENV{CONTENT_LENGTH}); 17: if ( $buf ne '' ){ 18: foreach ( split(/\s*;\s*/,$ENV{HTTP_COOKIE}) ){ 19: foreach ( split(/\,/,$_) ){ 20: ($key,$value) = split(/=/,$_); 21: $value =~ tr/+/ /; 22: $value =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg; 23: $FORM{$key} = $value; 24: } 25: } 26: } 27: 28: if ( $FORM{COOKIE_FLAG} eq 'on' ){ 29: ($name,$email,$url) = ($FORM{NAME},$FORM{EMAIL}); 30: foreach ( $name,$email,$url ){ # URL エンコード 31: s/([^-_a-zA-Z0-9 ])/sprintf("%%%02lX",unpack("C",$1))/eg; 32: s/ /+/g; 33: } 34: $cookie_data = 35: "Set-Cookie: NAME=$name,EMAIL=$email,URL=$url; expires=Mon, 30 Dec 2020 23:59:59 GMT\n"; 36: print $cookie_data; 37: } 38: 39: print "\n<HTML><BODY BGCOLOR=WHITE>\n"; 40: 41: if ( $ENV{HTTP_COOKIE} ){ 42: print "受け取った cookie: $ENV{HTTP_COOKIE}<P>\n"; 43: } 44: 45: if ( $cookie_data ){ 46: print "セットした cookie: $cookie_data<P>\n"; 47: } 48: 49: print <<END; 50: <FORM METHOD=POST ACTION="$ENV{REQUEST_URI}"> 51: <TABLE> 52: <TR><TD>名前: <TD><INPUT TYPE=TEXT NAME=NAME VALUE=$COOKIE{NAME}> 53: <TR><TD>メールアドレス: <TD><INPUT TYPE=TEXT NAME=EMAIL VALUE=$COOKIE{EMAIL}> 54: <TR><TD>Cookie を利用する: <INPUT TYPE=CHECKBOX NAME=COOKIE_FLAG><BR> 55: <TR><TD><INPUT TYPE=SUBMIT VALUE=OK><BR> 56: </TABLE> 57: </FORM> 58: </BODY></HTML> 59: END