1

パーセント エンコーディングに関するこの以前の SO の質問を見た後、どのスタイルのエンコーディングが正しいのか興味があります。パーセント エンコーディングに関するウィキペディアの記事では、コンテンツ タイプを保持しながら、スペース+の代わりに使用することを暗示しています。%20application/x-www-urlencoded

これにより、+vs . の%20動作は、URL のどの部分がエンコードされているかによって異なると考えられます。パス セグメントとクエリ文字列の違いは何ですか? この仕様の詳細と参考文献は大歓迎です。


: 文字の各オクテットが文字列になるという点で、英数字以外の文字は UTF-8 でエンコードされると想定してい%XXます。ここで間違っている場合は訂正してください (たとえば、utf-8 ではなく latin-1)。ただし、URL のさまざまな部分のエンコーディングの違いにもっと関心があります。

4

1 に答える 1

4

これにより、+vs . の%20動作は、URL のどの部分がエンコードされているかによって異なると考えられます。

特定の URL コンポーネントに依存するだけでなく、そのコンポーネントにデータが入力される状況にも依存します。

スペース文字をエンコードするための の使用は、HTTP 要求で送信される Web フォーム データに適用される形式に'+'固有です。application/x-www-form-urlencodedURL 自体には適用されません。

application/x-www-form-urlencoded形式は、HTML 仕様で W3C によって正式に定義されています。HTML 4.01 の定義は次のとおりです。

セクション 17.13.3 フォーム データの処理、ステップ 4: エンコードされたフォーム データ セットの送信

この仕様は、フォームで使用できるすべての有効な送信方法またはコンテンツ タイプを指定しているわけではありません。ただし、HTML 4 ユーザー エージェントは、次の場合に確立された規則をサポートする必要があります。

メソッドが「get」で、アクションが HTTP URI の場合、ユーザー エージェントはアクションの値を取得し、「?」を追加します。それに、「application/x-www-form-urlencoded」コンテンツ タイプを使用してエンコードされたフォーム データ セットを追加します。次に、ユーザー エージェントは、この URI へのリンクをトラバースします。このシナリオでは、フォーム データは ASCII コードに制限されています。

• メソッドが「post」で、アクションが HTTP URI の場合、ユーザー エージェントは、action 属性の値と、enctype 属性で指定されたコンテンツ タイプに従って作成されたメッセージを使用して、HTTP「post」トランザクションを実行します。

セクション 17.13.4 フォーム コンテンツ タイプ、application/x-www-form-urlencoded

これはデフォルトのコンテンツ タイプです。このコンテンツ タイプで送信されるフォームは、次のようにエンコードする必要があります。

1. コントロールの名前と値はエスケープされます。スペース文字は '+'に置き換えられ、[RFC1738] のセクション 2.2 で説明されているように予約文字がエスケープされます。キャラクター。改行は "CR LF" のペア (つまり、'%0D%0A') として表されます。

2. コントロールの名前/値は、ドキュメントに表示される順序でリストされています。名前と値は「=」で区切られ、名前と値のペアは「&」で区切られます。

対応する HTML5 定義 (セクション 4.10.22.3 フォーム送信アルゴリズムおよびセクション 4.10.22.6 URL エンコードされたフォーム データ) は、より洗練され詳細になっていますが、この議論の目的上、趣旨はほぼ同じです。

GETそのため、Web フォーム データが要求ではなくHTTP 要求を介して送信される状況では、Web フォーム データはURLコンポーネントPOSTを使用してエンコードされ、そのまま配置されます。application/x-www-form-urlencodedquery

RFC 3986ごと: Uniform Resource Identifier (URI): Generic Syntax :

URI 生成アプリケーションは、予約済みセット内の文字に対応するデータ オクテットをパーセント エンコードする必要があります。ただし、これらの文字が URI スキームによってそのコンポーネント内のデータを表すことが明確に許可されている場合を除きます。

'+'は予約文字です:

reserved    = gen-delims / sub-delims

gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"

sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
            / "*" / "+" / "," / ";" / "="

コンポーネントは、次の文字を許可するため、エンコードされていない文字をquery明示的に許可します。'+'sub-delims

unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"

pct-encoded = "%" HEXDIG HEXDIG

pchar       = unreserved / pct-encoded / sub-delims / ":" / "@"

query       = *( pchar / "/" / "?" )

そのため、Web フォーム送信のコンテキストでは、スペースはコンポーネント'+'にそのまま配置される前に を使用してエンコードされqueryます。のエンコードされた形式はコンポーネントapplication/x-www-form-urlencodedの定義と互換性があるため、これは URL 構文によって許可されます。query

たとえば、次のようになります。http://server/script?field=hello+world

queryただし、Web フォームの送信以外でコンポーネントにスペース文字を直接配置するにはpct-encoded、を使用する必要が' 'ありunreservedます。sub-delimsquery

たとえば、次のようになります。http://server/script?hello%20world

pathの使用により、同様のルールがコンポーネントにも適用されますpchar

  path          = path-abempty    ; begins with "/" or is empty
                / path-absolute   ; begins with "/" but not "//"
                / path-noscheme   ; begins with a non-colon segment
                / path-rootless   ; begins with a segment
                / path-empty      ; zero characters

  path-abempty  = *( "/" segment )
  path-absolute = "/" [ segment-nz *( "/" segment ) ]
  path-noscheme = segment-nz-nc *( "/" segment )
  path-rootless = segment-nz *( "/" segment )
  path-empty    = 0<pchar>
  segment       = *pchar
  segment-nz    = 1*pchar
  segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
                ; non-zero-length segment without any colon ":"

したがって、エンコードされていない文字pathは許可されますがsub-delims'+'文字はエンコードされたスペースとしてではなく、そのまま扱われます。 application/x-www-form-urlencodedはコンポーネントでは使用されないため、 と の定義によりpath、スペース文字は としてエンコードする必要があります。%20pcharsegment-nz-nc

さて、文字のエンコードに使用される文字セットについて-

Web フォーム送信の場合、その文字セットは、Web フォーム データを URL に挿入する前に準備するために使用される Web フォーム エンコーディング アルゴリズム (HTML4 よりも HTML5 の方が多い) で定義されたルールによって決定されます。簡単に言えば、HTML はaccept-charset属性または非表示_charset_フィールドをそれ自体で直接指定できます<form>。それ以外の場合、文字セットは通常、親 HTML で使用される文字セットです。

ただし、Web フォームの送信以外では、URL コンポーネントで非 ASCII 文字をエンコードするために charset を使用するための正式な標準はありません (一方、IRI構文では、特に IRI を URI に変換するときに UTF-8 が必要です)。 /URL)。IRI 以外では、文字セットを指定するのは特定の URI スキーム次第です (HTTP スキームは指定しません)。それ以外の場合は、サーバーが使用する文字セットを決定します。現在、ほとんどのスキーム/サーバーは UTF-8 を使用していますが、通常はサーバーのロケール (Latin1、Shift-JIS など) に基づいて、他の文字セットを使用するサーバー/スキームがまだいくつかあります。URL や HTTP ( Deterministic URI Encoding など) に文字セット レポートを直接追加する試みがありましたが、一般的には使用されていません。

于 2015-11-14T04:53:57.683 に答える