URL内のスペースがいつ+
にエンコードされ、いつそれが%20
にエンコードされますか?
Wikipedia (強調とリンクを追加)から:
HTMLフォームに入力されたデータが送信されると、フォームフィールドの名前と値がエンコードされ、GETまたはPOSTメソッドを使用してHTTPリクエストメッセージでサーバーに送信されます。 デフォルトで使用されるエンコーディングは、一般的なURIパーセントエンコーディングルールの非常に初期のバージョンに基づいており、改行の正規化やスペースの置換などの 変更の数 「%20」ではなく「+」。この方法でエンコードされたデータのMIMEタイプはapplication/x-www-form-urlencodedであり、現在定義されています(まだ非常に時代遅れの方法で) )HTMLおよびXForms仕様。
そのため、realパーセントエンコーディングは%20
を使用しますが、URLのフォームデータは+
を使用する修正された形式になります。そのため、クエリ文字列の+
の後のURLには、?
のみが表示される可能性が最も高くなります。
この混乱は、URLがまだ今日まで「壊れている」ためです。
例えば " http://www.google.com "を取ります。これはURLです。 URLはUniform Resource Locatorであり、実際にはWebページへのポインタです(ほとんどの場合)。 1994年の最初の仕様以来、URLは実際には非常に明確に定義された構造を持っています。
" http://www.google.com "のURLに関する詳細情報を抽出できます。
+---------------+-------------------+
| Part | Data |
+---------------+-------------------+
| Scheme | http |
| Host | www.google.com |
+---------------+-------------------+
次のようなもっと複雑なURLを見てください。
" https:// bob:[email protected]:8080/file; p = 1?q = 2#3 "
以下の情報を抽出することができます。
+-------------------+---------------------+
| Part | Data |
+-------------------+---------------------+
| Scheme | https |
| User | bob |
| Password | bobby |
| Host | www.lunatech.com |
| Port | 8080 |
| Path | /file;p=1 |
| Path parameter | p=1 |
| Query | q=2 |
| Fragment | third |
+-------------------+---------------------+
https://bob:[email protected]:8080/file;p=1?q=2#third
\___/ \_/ \___/ \______________/ \__/\_______/ \_/ \___/
| | | | | | \_/ | |
Scheme User Password Host Port Path | | Fragment
\_____________________________/ | Query
| Path parameter
Authority
予約文字はパートごとに異なります。
HTTP URLの場合、パスフラグメント部分のスペースは "%20"(絶対に "+"ではない)にエンコードする必要がありますが、パスフラグメント部分の "+"文字はエンコードしないでおくことができます。
クエリ部分では、スペースは "+"(後方互換性のため:URI標準で検索しないでください)または "%20"のいずれかにエンコードできます(このあいまいさの結果として)。 )を "%2B"にエスケープする必要があります。
これは、 "blue + light blue"の文字列は、パス部分とクエリ部分で異なる方法でエンコードする必要があることを意味します。
" http://example.com/blue+light%20blue?blue%2Blight+blue "#:。
そこから、完全に構築されたURLをエンコードすることは、URL構造の構文上の認識なしには不可能であると推測できます。
これは次のようになります。
%20
の前に?
を、後の+
を持つべきです。
私は%20
をお勧めします。
あなたはそれらをハードコーディングしていますか?
ただし、これは言語間であまり一貫性がありません。私が間違えていなければ、PHPでurlencode()
はスペースを+
として扱いますが、Pythonのurlencode()
はそれらを%20
として扱います。
編集:
私は間違っているようです。 Pythonのurlencode()
(少なくとも2.7.2では)はquote_plus()
の代わりにquote()
を使っているので、スペースを "+"としてエンコードします。また、W3Cの推奨はここにある "+"であるようです: http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1
そして実際に、スペースをエンコードするために何を使うべきかについてのPython自身の課題追跡システムに関するこの興味深い議論に従うことができます: http://bugs.python.org/issue13866 。
編集2:
私は ""の最も一般的なエンコード方法は "+"であることを理解していますが、単なる注意ですが、これは私にも当てはまるかもしれませんが、これは少し混乱します。
import urllib
print(urllib.urlencode({' ' : '+ '})
>>> '+=%2B+'
スペースは、URLの「application/x-www-form-urlencode」コンテンツタイプのキーと値のペアのクエリ部分で「+」にのみエンコードできます。これはMAYであり、MUSTではありません。他のURLでは、%20としてエンコードされています。
私の考えでは、URLのクエリ部分であっても、スペースを常に "+"ではなく%20としてエンコードするのが良いでしょう。 + "in" application/x-www-form-urlencodedされたコンテンツタイプのキーと値のペア。 (8.2.1項サブパラグラフ1を参照)
フォームデータをエンコードするこの方法は、後のHTML仕様にも記載されています。たとえば、HTML 4.01仕様書などにあるapplication/x-www-form-urlencodedに関する関連段落などを探します。
これはURLのサンプル文字列で、HTML仕様ではスペースをプラス記号としてエンコードできます。 " http://example.com/over/there?name=foo+bar "。そのため、 "?"の後にだけ、HTMLの仕様に従ってスペースをプラスに置き換えることができます。それ以外の場合は、スペースを%20にエンコードする必要があります。しかし、コンテキストを正しく判断するのは難しいので、スペースを "+"としてエンコードしないことがベストプラクティスです。
RFC-3986、p.2.3で定義されている「予約されていない」以外のすべての文字をパーセントエンコードすることをお勧めします。
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
実装は選択したプログラミング言語によって異なります。
URLに国別文字が含まれている場合は、まずそれらをUTF-8にエンコードしてから、結果をパーセントエンコードします。