[3] [[HTTP]] の [DFN[[CODE(HTTP)@en[Set-Cookie:]] [[応答頭欄]]]]は、 [[クライアント]]に対して [[Cookie]] を設定することを指示します。 * 仕様書 - [2] [[Netscape Cookie]] -- [CITE[Client Side State - HTTP Cookies]] * 構文 [4] [CODE(HTTP)@en[Set-Cookie:]] 欄の[[欄本体]]は [PRE(HTTP example code)[ Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure ]PRE] のように名前と値の組 ([RUBYB[[[属性]]]@en[attribute]]) の連続として記述します [SRC[>>2]]。 [6] ,[[属性名]],説明 ,[VAR[NAME]],>>7 ,[CODE(HTTP)@en[[[Expires]]]],有効期限 ,[CODE(HTTP)@en[[[Path]]]],対象となる [[path]] ,[CODE(HTTP)@en[[[Domain]]]],対象となる[[ドメイン]] ,[CODE(HTTP)@en[[[Secure]]]],[[安全]]でなければならないか否か ** 順序 [5] 名前と値の組の順序については明確に規定されていませんが、 [[Cookie]] として設定する名前と値の組の後に[[属性]]を適当な順番で記述します。 ** 大文字と小文字 [12] [[属性]]の名前や値の[[大文字と小文字を区別しない]]かどうかは仕様上明記されていません。 仕様書上は[[属性]]の名前はすべて[[小文字]]で記述されています。 ** [CODE(HTTP)@en[[VAR[NAME]]=[VAR[VALUE]]]] [7] [CODE(HTTP)@en[[[Set-Cookie:]]]] 欄にはまず最初に設定する名前と値の組を[[属性]]として指定します。 [8] この[[属性]]は必須です。 [SRC[>>2]] [17] [CODE(HTTP)@en[[[Domain]]]] と [CODE(HTTP)@en[[[Path]]]] と [CODE(HTTP)@en[[VAR[NAME]]]] が同じ [[Cookie]] があれば、 値は上書きされて、最新のものだけが残ります。 [SRC[>>2]] ;; [19] 仕様上は [CODE(HTTP)@en[[[Path]]]] と [CODE(HTTP)@en[[VAR[NAME]]]] とありますが、 [CODE(HTTP)@en[[[Domain]]]] も実際には見ています。 [20] >>17 の上書き判定における [CODE(HTTP)@en[[[Path]]]] は完全一致 [SRC[>>2]] なので、 例えば [CODE(URI)[/foo]] と [CODE(URI)[/foo/bar]] で同じ名前の [[Cookie]] が設定されると、 [CODE(URI)@en[/foo/bar]] では両方が有効になります。 *** 符号化 [9] 名前や値は任意の値ですが、 [CODE(char)[[[;]]]], [CODE(char)[[[,]]]], [RUBYB[[[空白]]]@en[white space]]は使えません。 [SRC[>>2]] [10] >>9 の記号を使いたい時の[[符号化]]の方法はありませんが、[[百分率符号化]]を用いることが[RUBYB[推奨]@en[recommended]]されています。 [SRC[>>2]] [11] 仕様上は >>9 の記号類以外の任意の[[文字]]が使えることになっていますが、その「[[文字]]」 全体の[[集合]]が何かは不明です。[[HTTP]] [[頭部]]で[[非ASCII文字]]を使う方法は標準不在な状況で、[CODE(HTTP)@en[[[Set-Cookie:]]]] 欄に関しても何ら [WEAK[(利用できるのかどうかも)]] 定められていません。 [[文書]]の[[文字コード]]や[[利用者エージェント]]の種類によって違った解釈をされる可能性があります。 現実の[[CGIスクリプト]]等の実装は特に気にしていなかったり、 [[百分率符号化]]を用いていたりです。[[百分率符号化]]を使うのは仕様書の >>10 の記述の影響でしょうか。 [13] [CODE(HTTP)@en[[[=]]]] も名前か値かその両方かで使えないはずなのですが、 仕様上は明記されていません。 ** 複数の [CODE(HTTP)@en[[[Set-Cookie:]]]] 欄 [16] 1つの [[HTTP]] [[応答]]内に複数の [CODE(HTTP)@en[[[Set-Cookie:]]]] [[頭欄]]を指定することができます。 [SRC[>>2]] [14] [CODE(char)[[[,]]]] の使用が禁止されているのは複数の [CODE(HTTP)@en[[[Set-Cookie:]]]] [[頭欄]]を連結した時に [CODE(char)[[[,]]]] が使われることへの配慮でしょうか、と思いきや、 [CODE(HTTP)@en[[[Expires]]]] では [CODE(char)[[[,]]]] が[[曜日]]の後に使われています。 それならなんで禁止されているのでしょう。 [15] [[HTTP]] 上は複数の同じ名前の[[頭欄]]を指定するのは1つの[[頭欄]]に [CODE(char)[[[,]]]] で併記するのと同義ですが、 >>14 のような状況なので、そのように解釈されることを当てにしない方が賢明です。 [18] 複数の [CODE(HTTP)@en[[[Set-Cookie:]]]] [[頭欄]]で同じ [CODE(HTTP)@en[[VAR[NAME]]]] が指定されていたときにどれが生き残るのか (>>17) は仕様に明記されていません。 * 処理モデル ** 利用者エージェントでの処理 [305] [[利用者エージェント]]は[[状態符号]]が[[リダイレクト]]であっても、 (その[[リダイレクト]]が帰ってきた[[要求]]の [[URL]] に関して) [CODE(HTTP)@en[[[Set-Cookie:]]]] [[頭欄]]に従った処理をするべきです。 ** キャッシュでの処理 [22] [[キャッシュ]]は [CODE(HTTP)@en[[[Set-Cookie:]]]] [[頭欄]]をそのまま[[クライアント]]に渡すべきです。 [[状態符号]]が [CODE(HTTP)@en[[[200]]]] であれ [CODE(HTTP)[[[304]]]] であれ、です。 [SRC[>>2]] *** キャッシュ可能性 [21] [CODE(HTTP)@en[[[Set-Cookie:]]]] [[頭欄]]は[[キャッシュ]]するべきではありません。 [SRC[>>2]] * メモ [1] [CITE[苦い開発: クッキーの有効期限の更新]] ([TIME[2009-06-06 09:06:11 +09:00]] 版) > Apache2.2 と IE6 でsetcookie()で既存の同じ名前と値を設定する場合、有効期限(期間)は更新されない。 有効期限0で一旦セットしてから同じ有効期間をセットする。 > [PRE(PHP example code)[ setcookie($name, $name, 0); setcookie($name, $name, time()+60*60*24*365); ]PRE]