URL中的空格何时编码为+,何时编码为%20?
+
%20
从维基百科(强调和链接添加):
当提交已输入超文本标记语言表单的数据时,表单字段名称和值将被编码,并使用GET或POST方法在HTTP请求消息中发送到服务器,或者在历史上通过电子邮件发送。默认情况下使用的编码是基于通用URI百分比编码规则的早期版本,具有修改次数,例如换行符规范化和将空格替换为“+”而不是“%20”。以这种方式编码的数据的MIME类型是应用程序/x-www-form-urLencode,目前它是在超文本标记语言和Xform规范中定义的(仍然以非常过时的方式)。
因此,真正%编码使用%20,而URL中的表单数据是使用+的修改形式。因此,您很可能只在?之后的查询字符串中的URL中看到+。
?
我会推荐%20。
你在硬编码吗?
不过,这在不同语言之间并不是很一致。如果我没弄错的话,PHPurlencode()将空格视为+,而Python的urlencode()将它们视为%20。
urlencode()
编辑:
看来我弄错了。Python的urlencode()(至少在2.7.2中)使用quote_plus()而不是quote(),因此将空格编码为“+”。看起来W3C的建议是“+”,如这里所示:http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1
quote_plus()
quote()
事实上,您可以在Python自己的问题跟踪器上关注关于使用什么来编码空间的有趣辩论:http://bugs.python.org/issue13866。
编辑#2:
我知道“”最常见的编码方式是“+”,但只是一个注释,可能只是我,但我觉得这有点令人困惑:
import urllibprint(urllib.urlencode({' ' : '+ '}) >>> '+=%2B+'
这种混乱是因为URL直到今天仍然“损坏”。
从一篇博客文章:
以“http://www.google.com”为例。这是一个URL。URL是一个统一资源定位器,实际上是指向网页的指针(在大多数情况下)。自1994年第一个规范以来,URL实际上具有非常明确的结构。我们可以提取有关“http://www.google.com”URL的详细信息:+---------------+-------------------+| Part | Data |+---------------+-------------------+| Scheme | http || Host | www.google.com |+---------------+-------------------+如果我们看一个更复杂的URL,例如:"https://bob:bobby@www.lunatech.com: 8080/file; p=1? q=2#第三"我们可以提取以下信息:+-------------------+---------------------+| Part | Data |+-------------------+---------------------+| Scheme | https || User | bob || Password | bobby || Host | www.lunatech.com || Port | 8080 || Path | /file;p=1 || Path parameter | p=1 || Query | q=2 || Fragment | third |+-------------------+---------------------+ https://bob:bobby@www.lunatech.com:8080/file;p=1?q=2#third\___/ \_/ \___/ \______________/ \__/\_______/ \_/ \___/| | | | | | \_/ | |Scheme User Password Host Port Path | | Fragment\_____________________________/ | Query| Path parameterAuthority每个部分的保留字符都不同。对于HTTP URL,路径片段部分中的空格必须编码为“%20”(不是,绝对不是“+”),而路径片段部分中的“+”字符可以不编码。现在在查询部分,空格可以编码为“+”(为了向后兼容:不要尝试在URI标准中搜索它)或“%20”,而“+”字符(由于这种歧义)必须转义为“%2B”。这意味着“蓝色+浅蓝色”字符串必须在路径和查询部分以不同的方式编码:“http://example.com/blue+light%20blue?blue%2Blight+blue"。从那里你可以推断出,如果没有URL结构的语法意识,编码一个完全构造的URL是不可能的。
以“http://www.google.com”为例。这是一个URL。URL是一个统一资源定位器,实际上是指向网页的指针(在大多数情况下)。自1994年第一个规范以来,URL实际上具有非常明确的结构。
我们可以提取有关“http://www.google.com”URL的详细信息:
+---------------+-------------------+| Part | Data |+---------------+-------------------+| Scheme | http || Host | www.google.com |+---------------+-------------------+
如果我们看一个更复杂的URL,例如:
"https://bob:bobby@www.lunatech.com: 8080/file; p=1? q=2#第三"
我们可以提取以下信息:
+-------------------+---------------------+| Part | Data |+-------------------+---------------------+| Scheme | https || User | bob || Password | bobby || Host | www.lunatech.com || Port | 8080 || Path | /file;p=1 || Path parameter | p=1 || Query | q=2 || Fragment | third |+-------------------+---------------------+ https://bob:bobby@www.lunatech.com:8080/file;p=1?q=2#third\___/ \_/ \___/ \______________/ \__/\_______/ \_/ \___/| | | | | | \_/ | |Scheme User Password Host Port Path | | Fragment\_____________________________/ | Query| Path parameterAuthority
每个部分的保留字符都不同。
对于HTTP URL,路径片段部分中的空格必须编码为“%20”(不是,绝对不是“+”),而路径片段部分中的“+”字符可以不编码。
现在在查询部分,空格可以编码为“+”(为了向后兼容:不要尝试在URI标准中搜索它)或“%20”,而“+”字符(由于这种歧义)必须转义为“%2B”。
这意味着“蓝色+浅蓝色”字符串必须在路径和查询部分以不同的方式编码:
“http://example.com/blue+light%20blue?blue%2Blight+blue"。
从那里你可以推断出,如果没有URL结构的语法意识,编码一个完全构造的URL是不可能的。
这可以归结为:
您应该在?之前有%20,在+之后有+。
来源
一个空格只能被编码为“+”在URL的“应用程序/x-loo-form-urlencoded”内容类型键值对查询部分。在我看来,这是一个可能,不是一个必须。在其余的URL中,它被编码为%20。
在我看来,最好始终将空格编码为%20,而不是“+”,即使在URL的查询部分也是如此,因为超文本标记语言规范(rfc1866)规定空格字符应编码为“+”在“应用程序/x-www-表格-urlencoded”内容类型键值对中(参见第8.2.1段)。
这种编码表单数据的方式也在后面的超文本标记语言规范中给出。例如,在超文本标记语言4.01规范中查找有关应用程序/x-www-表格-urlencoded的相关段落,等等。
这是URL中的一个示例字符串,其中超文本标记语言规范允许将空格编码为加号:"http://example.com/over/there?name=foo+bar";。因此,只有在“?”之后,空格才能被加号替换。在其他情况下,空格应该编码为%20。但由于很难正确确定上下文,因此最好不要将空格编码为"+"。
我建议对所有字符进行百分比编码,除了rfc3986中定义的“未保留”,第2.3页
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
实现取决于您选择的编程语言。
如果您的URL包含国家字符,请先将它们编码为UTF-8,然后对结果进行百分比编码。
总结一下这里(有些矛盾)的答案,我认为可以归结为:
| standard | + | %20 ||---------------+-----+-----|| URL | no | yes || query string | yes | yes || form params | yes | no || mailto query | no | yes |
所以从历史上看,我认为发生的事情是:
结果:我们最终得到了两种不同的方法来对URL中的空格进行编码,具体取决于你所谈论的部分。但它甚至没有违反URL标准。从URL的角度来看,“查询”只是一个黑盒。如果你想在那里使用除了百分比编码之外的其他编码:请自便。
但正如电子邮件示例所示,从表单参数实现中借用URL查询字符串可能会有问题。因此最终使用%20更安全,但可能没有开箱即用的库支持它。