【发布时间】:2011-02-10 08:03:38
【问题描述】:
有时空格的 URL 编码为 + 符号,有时则编码为 %20。有什么区别?为什么会发生这种情况?
【问题讨论】:
标签: urlencode
有时空格的 URL 编码为 + 符号,有时则编码为 %20。有什么区别?为什么会发生这种情况?
【问题讨论】:
标签: urlencode
+ 表示application/x-www-form-urlencoded 内容中的空格only,例如 URL 的查询部分:
http://www.example.com/path/foo+bar/path?query+name=query+value
在这个URL中,参数名是query name加空格,值是query value加空格,但是路径中的文件夹名字面意思是foo+bar,不是@ 987654330@.
%20 是在任一上下文中编码空间的有效方法。因此,如果您需要对字符串进行 URL 编码以包含在 URL 的一部分中,将空格替换为 %20 并将加号替换为 %2B 总是安全的。这就是,例如,encodeURIComponent() 在 JavaScript 中所做的。不幸的是,这不是urlencode 在 PHP 中所做的(rawurlencode 更安全)。
【讨论】:
<input name="query name" value="query value"> 的表单创建一个query+name=query+value 参数。它不会从表单创建query%20name,但使用它是完全安全的,例如。如果您自己为XMLHttpRequest 提交表单。如果您有一个带有空格的 URL,例如 <a href="http://www.example.com/foo bar/">,那么浏览器会将其编码为 %20 以便您纠正错误,但最好不要依赖它。
foo bar 变为foo+bar?
+,你自然可以做encodeURIComponent(s).replace(/%20/g, '+')
所以,这里的答案都有点不完整。 RFC 3986 中明确定义了使用 '%20' 对 URL 中的空格进行编码,它定义了 URI 的构建方式。本规范中没有提到使用 '+' 来编码空格 - 如果您只按照本规范,空格必须编码为 '%20'。
提到使用“+”编码空格来自 HTML 规范的各种化身 - 特别是在描述内容类型“application/x-www-form-urlencoded”的部分中。这用于发布表单数据。
现在,HTML 2.0 规范(RFC 1866) 在第 8.2.2 节中明确指出,GET 请求的 URL 字符串的 query 部分应编码为 '应用程序/x-www-form-urlencoded'。从理论上讲,这表明在查询字符串的 URL 中使用“+”是合法的(在“?”之后)。
但是……真的吗?请记住,HTML 本身就是一种内容规范,带有查询字符串的 URL 可以用于 HTML 以外的内容。此外,虽然 HTML 规范的更高版本继续在 'application/x-www-form-urlencoded' 内容中将 '+' 定义为合法,但它们完全省略了将 GET 请求查询字符串定义为该类型的部分。事实上,在 HTML 2.0 规范之后的任何内容中都没有提及查询字符串编码。
这给我们留下了一个问题——它有效吗?当然,有很多遗留代码支持查询字符串中的“+”,还有很多生成它的代码。因此,如果您使用“+”,您将不会中断。 (事实上,我最近对此进行了所有研究,因为我发现了一个主要站点未能在 GET 查询中接受“%20”作为空格。他们实际上未能解码任何 百分比编码字符。因此您使用的服务也可能是相关的。)
但是从纯粹的规范阅读来看,如果没有将 HTML 2.0 规范中的语言延续到更高版本中,则 URL 完全被 RFC 3986 覆盖,这意味着应该将空格转换为“%20”。如果您请求的不是 HTML 文档,那肯定是这种情况。
【讨论】:
%20 (<a href="?q=a b">),但是当您发送表单时,它使用 + 符号。您可以通过显式使用 + 符号 (<a href="?q=a+b">) 或使用 XMLHTTPRequest 发送表单来覆盖它。
http://www.example.com/some/path/to/resource?param1=value1
问号之前的部分必须使用 % 编码(所以%20 表示空格),问号之后可以使用%20 或+ 表示空格。如果您在问号后需要实际的+,请使用%2B。
【讨论】:
decodeURIComponent 不会对其进行解码。
+ 是一个保留字符,它将被浏览器保留。
+ 解码空格({ foo: 'bar bar'}.to_query => foo=bar+bar)
出于兼容性原因,最好始终将空格编码为“%20”,而不是“+”。
它是RFC 1866(HTML 2.0 规范),它指定在“application/x-www-form-urlencoded”内容类型键值对中空格字符应编码为“+”。 (见第 8.2.1 段第 1 小段)。这种编码表单数据的方式在后面的HTML规范中也有给出,寻找application/x-www-form-urlencoded的相关段落。
以下是 RFC 1866 允许将空格编码为加号的 URL 字符串示例:“http://example.com/over/there?name=foo+bar”。因此,根据 RFC 1866,只有在“?”之后,空格才能被加号替换。在其他情况下,空格应编码为 %20。但由于很难确定上下文,最好不要将空格编码为“+”。
我建议对除RFC 3986, p.2.3 中定义的“未保留”之外的所有字符进行百分比编码。
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
您可能希望将空格编码为“+”(一个字节)而不是“%20”(三个字节)的唯一情况是,当您确定如何解释上下文以及查询的大小时字符串很重要。
【讨论】:
有什么区别?查看其他答案。
我们什么时候应该使用+ 而不是%20?如果出于某种原因您想让 URL 查询字符串 (?.....) 或哈希片段 (#....) 更具可读性,请使用 +。示例:您实际上可以阅读:
https://www.google.se/#q=google+doesn%27t+encode+:+and+uses+%2B+instead+of+spaces
(%2B = +)
但以下内容更难阅读(至少对我而言):
我认为+ 不太可能破坏任何东西,因为谷歌使用+(参见上面的第一个链接)并且他们可能已经考虑过这一点。我自己会使用+,只是因为可读 + Google 认为没问题。
【讨论】: