什么时候空格应该被编码为+(+)或%20?

有时空格的URL编码为+符号,有时则编码为%20。有什么不同?为什么会发生这种情况?

322365 次浏览

+表示application/x-www-form-urlencoded内容中的空格只有,例如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替换加号总是安全的。这就是JavaScript中encodeURIComponent()所做的。不幸的是,这不是urlencode在PHP中所做的(rawurlencode更安全)。

另请参阅

HTML 4.01规范应用程序/x-www-form-urlencoded

# EYZ0

问号前面的部分必须使用%编码(因此%20表示空格),问号后面可以使用%20+表示空格。如果在问号后面需要一个实际的+,请使用%2B

有什么不同?请看其他答案。

什么时候我们应该使用+而不是%20?如果出于某种原因,您希望使URL查询字符串(?.....)或散列片段(#....)更具可读性,请使用+。例子:你可以这样读:

https://www.google.se/#q=google+doesn%27t+encode+:+and+uses+%2B+instead+of+spaces (%2B = +)

但下面的内容就很难读了(至少对我来说):

https://www.google.se/#q=google%20doesn%27t%20oops%20:%20%20this%20text%20%2B%20is%20different%20spaces

我认为+不太可能破坏任何东西,因为谷歌使用+(见上面的第一个链接),他们可能已经考虑过这一点。我自己将使用+,因为readable +谷歌认为它是可以的。

出于兼容性考虑,最好总是将空格编码为"%20",而不是"+"。

它是RFC 1866 (HTML 2.0规范),它规定空格字符应该被编码为"+"在“应用程序/ 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。但是由于很难确定上下文,所以最好不要将空格编码为"+"。

我建议对除“unreserved”之外的所有字符进行百分比编码。在RFC 3986中定义,第2.3页。

unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"

唯一需要将空格编码为"+"(一个字节)而不是"%20"(3个字节)是当您确定如何解释上下文时,并且当查询字符串的大小是至关重要的时候。

所以,这里的答案都有点不完整。使用“%20”来编码url中的空格是在RFC 3986中显式定义的,它定义了如何构建URI。在这个规范中没有提到使用'+'来编码空格——如果只使用这个规范,空格必须被编码为'%20'。

使用“+”作为编码空间的说法来自于HTML规范的各种版本——特别是在描述内容类型“application/x-www-form-urlencoded”的部分。这用于发布表单数据。

现在,HTML 2.0 规范 (RFC 1866)明确指出,在8.2.2节中,GET请求URL字符串的查询部分应该被编码为'application/x-www-form-urlencoded'。从理论上讲,这表明在查询字符串的URL中(在'?'之后)使用'+'是合法的。

但是…真的吗?请记住,HTML本身就是一种内容规范,带有查询字符串的url可以用于HTML以外的内容。此外,虽然HTML规范的后续版本继续将“+”定义为“application/x-www-form-urlencoded”内容中的合法类型,但它们完全省略了将GET请求查询字符串定义为该类型的部分。事实上,在HTML 2.0规范之后的任何规范中都没有提到查询字符串编码。

这给我们留下了一个问题——它有效吗?当然,有很多的遗留代码支持在查询字符串中使用'+',还有很多代码也会生成它。所以如果你使用'+',你就不会崩溃。(事实上,我最近做了所有关于这个问题的研究,因为我发现一个主要的站点无法接受得到查询中的'%20'作为一个空格。他们实际上未能解码# eyz2%编码字符。所以你使用的服务也可能是相关的。)

但是从规范的纯粹阅读来看,没有将HTML 2.0规范中的语言带入后期版本,url完全由RFC 3986覆盖,这意味着空格应该转换为'%20'。当然,如果你请求的不是HTML文档,就应该是这种情况。