8

バックエンド プラットフォームに関係なく、Cookie の値をエンコード/デコードするための標準が何であるか (または何かありますか?) を理解するのが困難です。

RFC 2109によると:

VALUE はユーザー エージェントに対して不透明であり、サーバーが選択した印刷可能な ASCII エンコーディングで、オリジン サーバーが送信することを選択したものである可能性があります。「不透明」とは、コンテンツが重要であり、オリジン サーバーにのみ関連することを意味します。実際、コンテンツは、Set-Cookie ヘッダーを調べれば誰でも読み取ることができます。

これは「サーバーがボス」のように聞こえ、適用するエンコーディングを決定します。これにより、両側で手動のエンコード/デコード処理を記述せずに、たとえば PHP バックエンドから Cookie を設定し、Python や Java などから読み取ることが非常に困難になります。

値をエンコードする必要があるとしましょう。ロシア語/"печенье (*} значения"/は、英数字以外の文字が追加された「Cookie 値」を意味します。

パイソン:

ほとんどすべての WSGI サーバーは同じことを行い、8 進リテラルはECMA-262 の厳密モードでは減価償却されていると多くの人が言っていますが、8 進リテラルをエンコード/デコードするPython のSimpleCookieクラスを使用します。え?

したがって、生の Cookie 値は次のようになります。"/\"\320\277\320\265\321\207\320\265\320\275\321\214\320\265 (*} \320\267\320\275\320\260\321\207\320\265\320\275\320\270\321\217\"/"

Node.js:

まったくテストしていませんが、JavaScript バックエンドは、16 進数のエスケープ/エスケープ解除を使用するネイティブのencodeURIComponentおよびdecodeURIComponent関数でそれを行うと思いますか?

PHP:

PHP は、 encodeURIComponentに似ていますが、まったく同じではないurlencodeを Cookie 値に適用します。

したがって、生の値は次のようになります。%2F%22%D0%BF%D0%B5%D1%87%D0%B5%D0%BD%D1%8C%D0%B5+%28%2A%7D+%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D1%8F%22%2F二重引用符で囲まれていません。

でも; JavaScriptvalue変数が上記の PHP でエンコードされた値を持っている場合、decodeURIComponent(value)が与えられ/"печенье+(*}+значения"/ます。スペースの代わりに「+」文字を参照してください。

Java、Ruby、Perl、.NET の状況は? どの言語が望ましい動作に従っている (または最も近い) か。実際、W3によって定義されたこれに対する標準はありますか?

4

3 に答える 3

4

ここで少し混乱していると思います。サーバーのエンコーディングはクライアントにとって重要ではありません。それが、RFC 2109 がここで言おうとしていることです。

http における Cookie の概念は、実生活でのこれと似ています。クラブへの入場料を支払うと、手首にインク スタンプが押されます。これにより、再度支払うことなく、クラブを退会して再入場することができます。バウンサーに手首を見せるだけです。この実際の例では、それがどのように見えるかは気にしません。通常の光では見えないことさえあります。重要なのは、用心棒がその物体を認識することだけです。それを洗い流してしまうと、再度支払うことなくクラブに再入場する権利が失われます。

HTTP でも同じことが起こっています。サーバーはブラウザで Cookie を設定します。ブラウザーがサーバーに戻ってくると (読み取り: 次の HTTP 要求)、サーバーに Cookie が表示されます。サーバーは Cookie を認識し、それに応じて動作します。このような Cookie は、「WasHereBefore」マーカーのような単純なものである可能性があります。繰り返しますが、ブラウザーがそれが何であるかを理解することは重要ではありません。Cookie を削除すると、サーバーは、インク スタンプを洗い流した場合にそのクラブの用心棒が行うように、以前にあなたを見たことがないかのように動作します。

現在、多くの Cookie は、セッション ID という重要な情報を 1 つだけ保存しています。それ以外はすべてサーバー側に保存され、そのセッション ID に関連付けられます。このシステムの利点は、実際のデータがサーバーから離れることはないため、信頼できることです。クライアント側に保存されているものはすべて改ざんされる可能性があり、信頼すべきではありません。

編集:コメントを読み、質問をもう一度読んだ後、あなたの状況と、プログラミング言語に任せるのではなく、Cookie の実際のエンコーディングに関心がある理由をようやく理解したと思います: 2 つの異なるソフトウェア環境がある場合同じサーバー (例: PerlPHP) の場合、他の言語によって設定された Cookie をデコードしたい場合があります。上記の例では、PHP は Perl cookie をデコードする必要があり、その逆も同様です。

Cookie にデータを保存する方法に標準はありません標準では、ブラウザが Cookieを受信したとおりに正確に送り返すとだけ述べられています。使用されるエンコード スキームは、プログラミング言語に適したものです。

実際の例に戻ると、英語を話す警備員とロシア語を話す警備員が 2 人います。両者は、1 種類のインク スタンプについて合意する必要があります。おそらくこれには、少なくとも一方が他方の言語を学ぶことが含まれます。

ブラウザーの動作は標準化されているため、サーバーで使用されている他のすべての言語で 1 つの言語のエンコード スキームを模倣するか、使用されているすべての言語で独自の標準化されたエンコード スキームを作成することができます。header()これを実現するには、高レベルのルーチンではなく、PHP などの低レベルのルーチンを使用する必要がある場合がありますstart_session()

ところで: 同様に、サーバー側のセッション データを格納する方法を決定するのは、サーバー側のプログラミング言語です。CGI::SessionPHP の$_SESSION配列を使用してPerl にアクセスすることはできません。

于 2013-03-05T20:11:27.557 に答える
2

Cookie がクライアントに対して不透明であっても、HTTP 仕様に準拠する必要があります。rfc2616は、すべての HTTP ヘッダーが ASCII (ISO-8859-1) であることを指定します。rfc5987はそれを拡張して他の文字セットをサポートしていますが、どの程度広くサポートされているかはわかりません。

于 2013-03-06T00:00:45.157 に答える
0

私は UTF8 にエンコードし、base64 エンコーディングでラップすることを好みます。高速でどこにでもあり、どちらの側でもデータを壊すことはありません。

ラップする場合でも、明示的に UTF8 に変換する必要があります。他の言語とランタイムは、Unicode をサポートしていますが、多くの Windows API のように、文字列を内部的に UTF8 として保存しない場合があります。私の経験では、Python 2.x は、明示的な変換なしで Unicode 文字列を正しく取得することはめったにありません。

エンコード: nativeString -> utfEncode() -> base64Encode()

デコード: base64Decode() -> utfDecode() -> nativeString

最近、私が知っているほとんどすべての言語がこれをサポートしています。汎用の単機能エンコードを探すこともできますが、私は慎重を期して 2 段階のアプローチを選択します... 特に外国語の文字セットでは。

于 2013-03-06T07:21:32.607 に答える