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。我在这里说这是参考,因为这是Google搜索“ php url解码符加号时中断”的高评价结果。
danielson317 '16

Answers:


170
  • URL的路径部分中的编码百分比有望被解码,但是
  • +路径组件中的任何字符都应按原义对待。

明确地说:+只是查询组件中的特殊字符。


12
+1不幸的是,许多野外的“ URL编码器/编码器”对此并不理解。例如sislands.com/coin70/week6/encoder.htm keyone.co.uk/tools-url-encoder.asp meyerweb.com/eric/tools/dencoder
leonbloy 2010年

11
@Stobor:需要引用。
bukzor 2012年

8
@Stobor RFC是否曾经声明过将+字符解释为查询组件中的空格?还是仅仅是“从野而外”的规则?
Pacerier

44
@Pacerier和@bukzor:RFC 1738(由2396和3986修改)定义了scheme(http:),authority(//server.example.com)和path(/myfile/mypage.htm)组件,并且没有定义该+字符的任何特殊含义。HTML规范将查询组件定义为mime类型application / x-www-form-urlencoded,其定义为“用+RFC1738 替换空格和其他特殊字符”。因此,它不是“从头开始”,而是来自公认的(非RFC)标准。
Stobor

2
.NET方法Server.UrlEncode还会错误地将空格编码为路径部分中的加号,这违反了HTTP规则。
Suncat2000

243

您可以在W3Schools上找到一个不错的URL编码字符列表。

  • + 变成 %2B
  • 空间变成 %20

18
文字“ +”字符出现在URL 的路径组件中是完全合法的。
山姆·斯坦斯比

4
要使文字+被后端(或至少PHP)接收,必须对其进行三重编码:%25252B
Umbrella

11
这个答案与这个问题完全无关。
NisseEngström'7

22

空格字符只能在一种情况下编码为“ +”:application / x-www-form-urlencoded键/值对。

RFC-1866(HTML 2.0规范),第8.2.1段。第1小节说:“表单字段名称和值被转义:用'+'替换空格字符,然后转义保留字符”)。

这是URL中此类字符串的示例,其中RFC-1866允许将空格编码为正号:“ 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,它适用于Browser和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 '18

谢谢,它真的帮助了我!
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
我发现两个人投票赞成这个答案很奇怪。它实际上与这个问题无关。
2014年

1
其他字符* @-_ +怎么样。/
拉维2014年

1
@AndrewBarber为什么您发现它无关紧要?+成为%2B
The Java Guy 2015年

出于多种原因,这是错误的... escape不建议使用,而应使用encodeURI或,如果使用查询part 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

3
RFC 1738确实将加号视为空格。这完全取决于您的编码/解码功能是由哪个实现的。例如,在PHP,rawurlencode遵循RFC 1738而进行urlencode遵循RFC 2396
乔纳森Fingland

1
看,现在我还有其他困惑。在上面您给我的示例中,a.com%2Fa%2Bb不是我想要的,至少是a.com/a%2Bb。这是我要处理的实际URL,而不是作为查询字符串中的参数传递的URL。为了提供一些背景知识,Mac OS X Finder会将文件系统URL返回给我。因此,如果我有一个名为“ a?+ b.txt”的文件,它将返回类似于“ file://a%3F+b.txt”的文件,而不是“ file://a%3F%2B.txt”的文件。查找器是不正确的,还是查询字符串之前的+实际上是加号?
Francisco Ryan Tolmasky I 2009年

2
乔纳森:您确定1738说+保留吗?我看到:safe =“ $” | “-” | “ _” | “。” | “ +”未保留= alpha | 数字| 安全| 额外内容以及:因此,仅字母数字,特殊字符“ $ -_。+!*'()”以及用于保留目的的保留字符可以在URL中未经编码使用。
tlrobinson

2
“你要永远逃脱”需要更多的限定条件,而答案与这个问题无关。
错误
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.