URLスキーム/ホスト/パスの `+`はスペースを表しますか?


224

+URLのクエリ文字列のaがスペースを表すことを知っています。これはクエリ文字列領域外の場合にも当てはまりますか?つまり、次のURLを実行します。

http://a.com/a+b/c

実際に表す:

http://a.com/a b/c

(したがって、それが実際にである必要がある場合は、エンコードする必要があります+)、または実際に実際に表すのa+b/cですか?



4
PHPでは、urldecodeは%2b(+をエンコード)をスペースにデコードすることに注意してください。これを避けるためにrawurldecode。これは参考のためにここで言います。これは、「php urlデコードがプラス記号で壊れる」に対するGoogle検索の評価が高い結果であるためです。
danielson317 2016年

回答:


170
  • URLのパスセクション内のパーセントエンコードはデコードされると予想されますが、
  • 任意の+パスコンポーネント内の文字はリテラルとして扱われることが期待されます。

明示的+に言うと、これはクエリコンポーネントの特殊文字にすぎません。


12
+1残念ながら、世の中に出回っている多くの「URLコーダー/エンコーダー」はこれを理解していません。例:sislands.com/coin70/week6/encoder.htm keyone.co.uk/tools-url-encoder.asp meyerweb.com/eric/tools/dencoder
leonbloy

11
@Stobor:引用が必要です。
bukzor 2012年

8
@Stobor RFC +は、文字がクエリコンポーネントのスペースとして解釈されることをこれまでに述べましたか?それとも単に「自然界から」のルールですか?
パセリエ2012

44
@Pacerierと@bukzor:RFC 1738(2396および3986によって変更)は、スキーム(http:)、権限(//server.example.com)、およびパス(/myfile/mypage.htm)コンポーネントを定義し、+文字の特別な意味は定義していません。HTML仕様では、クエリコンポーネントをMIMEタイプapplication / x-www-form-urlencodedと定義しています。これは、「+RFC1738のようにスペースを他の特殊文字で置き換える」と定義されています。したがって、それは「自然界から」ではなく、受け入れられた(非RFC)標準からのものです。
Stobor

2
.NETメソッドServer.UrlEncodeは、パス部分のスペースもプラスとして誤ってエンコードし、HTTPルールに違反します。
Suncat2000 2015年

243

W3Schoolsで、対応するURLエンコード文字の優れたリストを見つけることができます。

  • + なる %2B
  • スペースは %20

18
URLのパスコンポーネントにリテラルの「+」文字を使用することは完全に合法です。
Sam Stainsby 2012年

4
リテラル+を取得する(少なくともPHPで、または)バックエンドによって受信されることが三重符号化されなければならない:%25252B

11
この回答は質問とはまったく関係ありません。
NisseEngström2017

22

スペース文字は、1つのコンテキストで "+"としてのみエンコードできます:application / x-www-form-urlencoded Key-Valueペア。

RFC-1866(HTML 2.0仕様)、パラグラフ8.2.1。サブパラグラフ1は次のように述べています。「フォームフィールドの名前と値はエスケープされます。スペース文字は `+ 'に置き換えられ、予約文字はエスケープされます。」

RFC-1866がスペースをプラスとしてエンコードできるURLのそのような文字列の例は次のとおりです: " http://example.com/over/there?name=foo+bar "。したがって、「?」の後のみ、スペースをプラスで置き換えることができます(他の場合では、スペースは%20にエンコードする必要があります)。このフォームデータのエンコード方法は、後のHTML仕様でも提供されています。たとえば、HTML 4.01仕様でapplication / x-www-form-urlencodedに関する関連する段落を探します。

ただし、常にコンテキストを正しく判断することは難しいため、スペースを「+」としてエンコードしないことがベストプラクティスです。RFC-3986、p.2.3で定義されている「予約されていない」以外のすべての文字をパーセントエンコードすることをお勧めします。エンコードする必要があるものを示すコード例を次に示します。これはDelphi(pascal)プログラミング言語で提供されていますが、所有する言語に関係なく、どのプログラマーにとってもそれがどのように機能するかを理解するのは非常に簡単です。

(* percent-encode all unreserved characters as defined in RFC-3986, p.2.3 *)
function UrlEncodeRfcA(const S: AnsiString): AnsiString;
const    
  HexCharArrA: array [0..15] of AnsiChar = '0123456789ABCDEF';
var
  I: Integer;
  c: AnsiChar;
begin
 // percent-encoding, see RFC-3986, p. 2.1
  Result := S;
  for I := Length(S) downto 1 do
  begin
    c := S[I];
    case c of
      'A' .. 'Z', 'a' .. 'z', // alpha
      '0' .. '9',             // digit
      '-', '.', '_', '~':;    // rest of unreserved characters as defined in the RFC-3986, p.2.3
      else
        begin
          Result[I] := '%';
          Insert('00', Result, I + 1);
          Result[I + 1] := HexCharArrA[(Byte(C) shr 4) and $F)];
          Result[I + 2] := HexCharArrA[Byte(C) and $F];
        end;
    end;
  end;
end;

function UrlEncodeRfcW(const S: UnicodeString): AnsiString;
begin
  Result := UrlEncodeRfcA(Utf8Encode(S));
end;

0

encodeURIComponent関数を使用してURLを修正します。これはブラウザとnode.jsで機能します

res.redirect("/signin?email="+encodeURIComponent("aaa+bbb-ccc@example.com"));


> encodeURIComponent("http://a.com/a+b/c")
'http%3A%2F%2Fa.com%2Fa%2Bb%2Fc'

1
これは問題に対処していません。また、特定の言語(JavaScript)でURLを誤ってエンコードします-コンテキストによっては、URLが機能するために特別な(リテラルではない)スラッシュ(/)とコロン(:)が必要な場所をエンコードしたくない場合があります。
Gremio

ありがとう、本当に助かりました!
qwsd

-2

以下をお試しください:

<script type="text/javascript">

function resetPassword() {
   url: "submitForgotPassword.html?email="+fixEscape(Stringwith+char);
}
function fixEscape(str)
{
    return escape(str).replace( "+", "%2B" );
}
</script>

2
2人がこの回答に投票したのは非常に奇妙です。それは文字通り質問とは何の関係もありません。
アンドリューバーバー

1
他の文字についてはどうですか* @-_ +。/
ラビ

1
@AndrewBarberなぜあなたはそれが無関係であると思いましたか?+は%2Bになり
ます

これは多くの理由で間違っています... escapeは非推奨です。代わりに、encodeURIまたはクエリ部分の場合に使用する必要がありますencodeURIComponent。また、パラメータ文字列はw3cに従ってエンコードする必要があります。
クリストフ

-5

あなたはいつもURLをエンコードするべきです。

RubyがURLをエンコードする方法は次のとおりです。

irb(main):008:0> CGI.escape "a.com/a+b"
=> "a.com%2Fa%2Bb"

8
私はそれが正しいと確信していません。RFC2396(ietf.org/rfc/rfc2396.txt)によれば、プラス記号はURIのパス(セグメント)の予約文字ではなく、クエリコンポーネントのみです。これは、URLエンコードする必要がないため、パス内のスペースとして解釈されるべきではなく、クエリ内でのみ解釈されることを意味しているようです。
tlrobinson 2009年

3
ただし、rfc 1738はプラスをスペースとして扱います。それはすべて、エンコード/デコード関数によって実装されているものに依存します。でurlencodeは、RFC 2396に続くのに対し、例えば、PHPで、rawurlencodeは、RFC 1738に従う
ジョナサンFingland

1
ほら、今、私はさらに混乱しています。上記の例では、a.com%2Fa%2Bbは私が望むものではなく、少なくともa.com/a%2Bbです。これは私が扱っている実際のURLであり、クエリ文字列のパラメータとして渡されるURLではありません。明確にするのに役立つかもしれない少しの背景のために、Mac OS X Finderは私にファイルシステムURLを返しています。したがって、「a?+ b.txt」という名前のファイルがある場合、「file://a%3F%2B.txt」ではなく、「file://a%3F+b.txt」のようなものを返します。 。ファインダーは正しくありませんか、それともクエリ文字列の前の+は実際にはプラスですか?
Francisco Ryan Tolmasky I

2
ジョナサン:1738は+は予約されていると言っていますか?わかりました:safe = "$" | 「-」| 「_」| 「」| "+"予約なし=アルファ| 数字| 安全| extraと同様に、したがって、英数字、特殊文字「$ -_。+!* '()」、および予約目的で使用される予約文字のみが、URL内でエンコードされずに使用できます。
tlrobinson 2009年

2
「あなたは常に脱出する」にはもっと資格が必要であり、答えはとにかく質問とは無関係です。
バグ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.