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 方案/主机/路径中的 `+` 是不是代表空格?的主要内容,如果未能解决你的问题,请参考以下文章