URL 方案/主机/路径中的 `+` 是不是代表空格?

Posted

技术标签:

【中文标题】URL 方案/主机/路径中的 `+` 是不是代表空格?【英文标题】:Does a `+` in a URL scheme/host/path represent a space?URL 方案/主机/路径中的 `+` 是否代表空格? 【发布时间】:2010-11-03 14:09:15 【问题描述】:

我知道 URL 的查询字符串中的 + 代表一个空格。这也是查询字符串区域之外的情况吗?也就是说,做如下网址:

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

实际代表:

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

(因此如果它实际上应该是+,则需要对其进行编码),还是它实际上代表a+b/c

【问题讨论】:

w3schools.com/tags/ref_urlencode.asp 请注意,在 php 中,urldecode 将 %2b(编码 +)解码为空格。为避免这种情况,请使用 rawurldecode。我在这里说这个以供参考,因为这是谷歌搜索“加号上的 php url 解码中断”的高评价结果。 When to encode space to plus (+) or %20?的可能重复 【参考方案1】:

您应该始终对 URL 进行编码。

以下是 Ruby 对 URL 的编码方式:

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

【讨论】:

我不确定这是否正确。根据 RFC2396 (ietf.org/rfc/rfc2396.txt) plusses 不是 URI 路径(段)中的保留字符,只有查询组件。这似乎意味着它们不需要进行 URL 编码,因此不应将其解释为路径中的空格,而应仅在查询中。 rfc 1738 确实将加号视为空格。这完全取决于您的编码/解码功能实现了哪个。例如,在 php 中,rawurlencode 遵循 rfc 1738,而 urlencode 遵循 rfc 2396。 看,现在我有一些额外的困惑。在你上面给我的例子中,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” .查找器只是不正确,还是查询字符串之前的 + 实际上是加号? Jonathan:你确定 1738 说 + 是保留的吗?我明白了:安全 = "$" | "-" | "_" | “。” | "+" 未保留 = alpha |数字 |安全 | extra 以及:因此,只有字母数字、特殊字符“$-_.+!*'()”和用于其保留目的的保留字符可以在 URL 中未编码使用。 “你总要逃跑”需要更多的限定,反正答案与问题无关。【参考方案2】:

您可以在W3Schools 上找到相应的 URL 编码字符列表。

+ 变为 %2B 空格变成%20

【讨论】:

在 URL 的 path 组件中出现文字“+”字符是完全合法的。 要让后端(或至少 PHP)接收到文字 +,它必须进行三重编码:%25252B 这个答案与问题完全无关。【参考方案3】: 预计会解码 URL 路径部分中的百分比编码,但是 路径组件中的任何 + 字符都应按字面意思处理。

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

https://www.rfc-editor.org/rfc/rfc3986

【讨论】:

+1 不幸的是,野外的许多“URL 编码器/编码器”并不理解这一点。例如sislands.com/coin70/week6/encoder.htmkeyone.co.uk/tools-url-encoder.aspmeyerweb.com/eric/tools/dencoder @Stobor RFC 是否曾声明 + 字符在查询组件中被解释为空格?或者它只是“来自野外”的规则? @Pacerier and @bukzor: RFC 1738(由 2396 和 3986 修改)定义了方案 (http:)、权限 (//server.example.com) 和路径 (/myfile/mypage.htm) 组件,并且没有为+ 字符定义任何特殊含义。 html 规范将查询组件定义为 MIME 类型 application/x-www-form-urlencoded,其定义为“用 + 和其他特殊字符替换空格,如 RFC1738 中的”。所以它不是“来自野外”,而是来自公认的(非 RFC)标准。 .NET 方法 Server.UrlEncode 错误地将空格编码为路径部分中的加号,这违反了 HTTP 规则。 @LawrenceDol 进一步“除了那些有草坪的人通常没有割草机”并不意味着“有草坪的人必须有割草机”。【参考方案4】:

试试下面:

<script type="text/javascript">

function resetPassword() 
   url: "submitForgotPassword.html?email="+fixEscape(Stringwith+char);

function fixEscape(str)

    return escape(str).replace( "+", "%2B" );

</script>

【讨论】:

我觉得很奇怪有两个人投了这个答案。它实际上与问题无关。 其他字符怎么样 * @ - _ + 。 / @AndrewBarber 为什么你觉得这无关紧要? + 变成 %2B 这是错误的,原因有很多... escape 已被弃用,您应该使用encodeURI 或查询部分encodeURIComponent。参数字符串也应该根据w3c进行编码。【参考方案5】:

使用 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'

【讨论】:

这并没有解决问题。并且,使用特定语言 (JavaScript) 错误地编码 URL - 根据上下文,您可能不想在需要特殊(非文字)斜杠 (/) 和冒号 (:) 以使 URL 工作的地方进行编码. 感谢它对我的帮助!【参考方案6】:

空格字符只能在一种情况下编码为“+”: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;

【讨论】:

以上是关于URL 方案/主机/路径中的 `+` 是不是代表空格?的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 apache http 服务器中 Location 标记中的上下文路径删除 url 中的空参数

使用 Apache 将 URL 路径视为虚拟主机

java中的绝对路径和相对路径

IOS:url目录路径中的文件

网址中的两条斜杠是啥意思

如何从 Redshift 中的字符串中解析主机?