19

したがって、PHP と Cookie に関する私の理解から、setcookie()関数を使用すると、自動的に URL エンコードされた Cookie が取得されます。そして、$_COOKIE配列に移動すると、自動的に URL がデコードされた Cookie が返されます。問題は、 を調べたときに Cookie を 2 回デコードしているように見えることです$_COOKIE

値が "Name|ID|Email" の Cookie があるとします。たとえば、次のようになります。

Joe|123|my+email@somewhere.com

これは次のようにエンコードされます。

Joe%7C123%7Cmy%2Bemail%40somewhere.com

プラス記号がエンコードされていることに注意してください。理論的には、デコードすると元に戻るはずです。これは で自動的に行われる$_COOKIEため、元の状態に戻す必要があります。しかし、代わりに、私は戻ってきています:

Joe|123|私のメールアドレス@somewhere.com

プラスがあったスペースに注目してください。urldecode()これは、Cookieで追加を実行した場合に期待することです。しかし、そうではないので、プラスの代わりにスペースを取得する理由がわかりません。

もう一つの興味深いひねり。ページを更新すると、正しい出力が生成されるようです。なぜこのように振る舞うのか、何か考えはありますか?

参考までに、初期 Cookie を設定するには、javascript とescape()スクリプトを使用してエンコードされた文字列を生成します。これは、javascript と PHP の間の引き継ぎの問題でしょうか?

考えをいただければ幸いです。

4

3 に答える 3

6

「%20」と「+」の両方が空白文字の有効なエンコーディングであることに注意してください。URL エンコーディングに関するウィキペディアの記事によると(強調を追加):

HTML フォームに入力されたデータが送信されると、フォーム フィールドの名前と値がエンコードされ、メソッド GET または POST を使用して HTTP 要求メッセージでサーバーに送信されるか、従来は電子メールを介して送信されます。デフォルトで使用されるエンコーディングは、一般的な URI パーセント エンコーディング ルールの非常に初期のバージョンに基づいており、改行の正規化やスペースを "%20" ではなく "+" に置き換えるなど、多くの変更が加えられています。この方法でエンコードされたデータの MIME タイプは application/x-www-form-urlencoded であり、現在 HTML および XForms 仕様で定義されています (まだ非常に古い方法です)。

より具体的には PHP と JavaScript に関連するものについては、この質問に対する一番上の回答を参照してください。

スペースをプラス (+) または %20 にエンコードするのはいつですか?

于 2013-01-17T16:55:25.903 に答える
2

まず、PHP は常に JavaScript の前に実行されます。これはクライアント側ではなくサーバー側であるため、JavaScript で設定した Cookie は、ページを更新するまで実際には PHP で使用できません (したがって、その問題)。

次の JavaScript には、文字列をエンコードするさまざまな方法があります。PHP で自動的に動作するのは 1 つだけです。

そう:

document.cookie = "testuser=" + "Joe|123|my+email@somewhere.com";
// Joe|123|my email@somewhere.com (when decoded by PHP)

document.cookie = "testuser=" + escape("Joe|123|my+email@somewhere.com");
// Joe|123|my email@somewhere.com (when decoded by PHP)

document.cookie = "testuser=" + encodeURI("Joe|123|my+email@somewhere.com");
// Joe|123|my email@somewhere.com (when decoded by PHP)

document.cookie = "testuser=" + encodeURIComponent("Joe|123|my+email@somewhere.com");
// Joe|123|my+email@somewhere.com 

したがって、テストのためにこれを試してください (Cookie の値を確認するには、ページを更新する必要があることに注意してください)。

<html>
<head>
    <title>Cookie Juggling</title>
    <script type="text/javascript">
        document.cookie = "testuser=" + encodeURIComponent("Joe|123|my+email@somewhere.com");
    </script>
</head>

<body>
    <div><?php echo !empty($_COOKIE['testuser']) ? $_COOKIE['testuser'] : "Cookie not set yet"; ?></div>
</body>
</html>
于 2013-01-17T17:15:48.340 に答える
2

Cookie を自動的にエンコードしたくない場合は、setrawcookie関数を使用できます。
この関数の例外は、次の文字を使用できないことです: (,; \t\r\n\013\014) :

setrawcookie("NAME","Joe|123|my+email@somewhere.com");  

# Output in browser:   
Joe|123|my+email@somewhere.com 

# Output in PHP `echo $_COOKIE['NAME']`:  
Joe|123|my email@somewhere.com

PHP 5.3 でテスト済み

setcookie("NAME","Joe|123|my+email@somewhere.com");

# Output in browser:  
Joe%7C123%7Cmy%2Bemail%40somewhere.com  

# Output in PHP echo $_COOKIE['NAME']`:  
Joe|123|my+email@somewhere.com  

now :別の方法としてsetcookie()、 とrawurldecode()を使用してデコードできます。

 echo rawurldecode($_COOKIE['NAME'])
于 2013-01-17T17:09:38.473 に答える