クッキー名と値の両方で許可されている文字は何ですか? それらは URL と同じですか、それとも共通のサブセットですか?
私が質問する理由は、最近、-
名前に が含まれる Cookie で奇妙な動作が発生し、それがブラウザ固有のものか、または私のコードに問題があるのか疑問に思っているからです。
ベストアンサー1
昔のネットスケープによるとクッキー仕様文字列全体は次NAME=VALUE
のようになります。
セミコロン、カンマ、空白を除いた文字のシーケンス。
それで-
動作するはずですし、私が持っているブラウザでは問題ないようです。どこで問題が発生しているのでしょうか?
上記から次のことが推測されます:
=
含めることは許可されていますが、あいまいになる可能性があります。ブラウザは常に文字列の最初の記号で名前と値を分割する=
ため、実際には=
VALUE に記号を入れることはできますが、NAME には入れることができません。
Netscape は仕様を記述するのが下手だったため言及されていませんが、ブラウザによって一貫してサポートされているようです:
NAME または VALUE のいずれかが空の文字列になる場合があります
文字列内に記号がまったく含まれていない場合
=
、ブラウザはそれを空の文字列名を持つ Cookie として扱います。つまり、 はSet-Cookie: foo
と同じですSet-Cookie: =foo
。ブラウザが空の名前の Cookie を出力する場合、等号は省略されます。そのため、
Set-Cookie: =bar
が生成されますCookie: bar
。名前や値内のカンマやスペースは実際には機能しているようですが、等号の周りのスペースは切り取られます。
制御文字(
\x00
プラス)\x1F
は\x7F
使用できません
言及されておらず、ブラウザ間でまったく一貫性がないのは、非 ASCII (Unicode) 文字です。
- Opera および Google Chrome では、UTF-8 で Cookie ヘッダーにエンコードされます。
- IE では、マシンのデフォルトのコード ページが使用されます (ロケール固有であり、UTF-8 は使用されません)。
- Firefox (および他の Mozilla ベースのブラウザ) は、各 UTF-16 コード ポイントの下位バイトを独自に使用します (したがって、ISO-8859-1 は問題ありませんが、それ以外は文字化けします)。
- Safari は、ASCII 以外の文字を含む Cookie の送信を拒否します。
そのため、実際には、クッキーで非 ASCII 文字を使用することはできません。Unicode、制御コード、またはその他の任意のバイト シーケンスを使用する場合、cookie_spec では、独自に選択したアドホック エンコード スキームを使用することが要求され、encodeURIComponent
合理的な選択肢として URL エンコード (JavaScript の によって生成されるもの) が提案されます。
実際の標準に関しては、Cookie の動作を体系化する試みはいくつかありましたが、これまでのところ、現実世界を反映したものはありません。
RFC 2109オリジナルのNetscape cookie_specをコード化して修正する試みでした。この標準では、より多くの特殊文字が禁止されています。RFC 2616トークン (a はここでも
-
許可されます)は許可されず、引用符で囲まれた文字列では他の文字とともに値のみを指定できます。この仕様の制限、引用符で囲まれた文字列とエスケープの特別な処理、または新しい機能を実装したブラウザはありません。RFC 29652109 を整理し、「バージョン 2 クッキー」スキームで機能を追加するという、もう 1 つの試みでした。これも誰も実装しませんでした。この仕様には、以前のバージョンと同じトークンと引用符で囲まれた文字列の制限があり、同じくらいナンセンスです。
RFC 6265は、歴史的な混乱を解消するための HTML5 時代の試みです。まだ現実と完全に一致しているわけではありませんが、以前の試みよりもはるかに優れています。少なくとも、ブラウザーがサポートするものの適切なサブセットであり、動作するはずなのに動作しない構文 (以前の引用符で囲まれた文字列など) は導入されていません。
6265 では、Cookie 名は引き続き RFC 2616 として指定されておりtoken
、英数字に加えて以下から選択できます。
!#$%&'*+-.^_`|~
クッキー値では、(ブラウザによってフィルタリングされる)制御文字と(一貫性のない実装の)非 ASCII 文字が正式に禁止されます。cookie_spec のスペース、カンマ、セミコロンの禁止は保持され、さらに以前の RFC を実際に実装した愚か者との互換性のために、値全体を囲む引用符以外のバックスラッシュと引用符も禁止されました(ただし、その場合、引用符は値の一部と見なされ、エンコード スキームとは見なされません)。つまり、英数字と次の文字が残ります。
!#$%&'()*+-./:<=>?@[]^_`{|}~
現実世界では、私たちはまだ元の最悪の Netscape cookie_spec を使用しているため、クッキーを消費するコードは、ほとんどあらゆる状況に遭遇する準備をする必要がありますが、クッキーを生成するコードの場合は、RFC 6265 のサブセットを使用することをお勧めします。