这个问题在这里已经有了答案: URL encoding the space character: + or %20? (5 个回答) 8 个月前关闭。
有时空格的 URL 编码为 +
符号,有时则为 %20
。有什么区别,为什么会发生这种情况?
+
表示 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
,不是 foo bar
。
%20
是在任一上下文中编码空间的有效方法。因此,如果您需要对字符串进行 URL 编码以包含在 URL 的一部分中,将空格替换为 %20
并将加号替换为 %2B
总是安全的。这就是,例如,encodeURIComponent()
在 JavaScript 中所做的。不幸的是,这不是 urlencode 在 PHP 中所做的(rawurlencode 更安全)。
也可以看看
HTML 4.01 Specification application/x-www-form-urlencoded
所以,这里的答案都有点不完整。在 RFC 3986 中明确定义了使用“%20”对 URL 中的空格进行编码,它定义了 URI 的构建方式。本规范中没有提到使用 '+' 来编码空格 - 如果您仅按照本规范进行,则必须将空格编码为 '%20'。
提到使用“+”编码空间来自 HTML 规范的各种化身 - 特别是在描述内容类型“application/x-www-form-urlencoded”的部分中。这用于发布表单数据。
现在,HTML 2.0 规范 (RFC 1866) 在第 8.2.2 节中明确指出,GET 请求的 URL 字符串的 query 部分应编码为 'application/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 的相关段落。
这是一个 URL 字符串示例,其中 RFC 1866 允许将空格编码为加号:“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 使用 +
(请参阅上面的第一个链接)并且他们可能已经考虑过这一点。我将自己使用 +
只是因为 readable + Google 认为它还可以。
不定期副业成功案例分享
<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, '+')