841

URL 中的空格何时编码为+,何时编码为%20

4

4 回答 4

484

来自维基百科(强调和链接添加):

当提交已输入 HTML 表单的数据时,表单字段名称和值将被编码并使用方法 GET 或 POST 或过去通过电子邮件在 HTTP 请求消息中发送到服务器。默认使用的编码基于通用 URI 百分比编码规则的早期版本,并进行了许多修改,例如换行规范化和用“+”而不是“%20”替换空格。以这种方式编码的数据的 MIME 类型是 application/x-www-form-urlencoded,目前在 HTML 和 XForms 规范中定义(仍然以非常过时的方式)。

因此,真正的百分比编码使用%20,而 URL 中的表单数据是使用+. 因此,您很可能只+在查询字符串中的 URL 中看到?.

于 2009-10-27T23:26:24.420 回答
366

这种混淆是因为 URL 直到今天仍然“损坏”。

来自博客文章

以“http://www.google.com”为例。这是一个网址。URL 是统一资源定位器,实际上是指向网页的指针(在大多数情况下)。自 1994 年第一个规范以来,URL 实际上具有非常明确的结构。

我们可以提取有关“http://www.google.com”网址的详细信息:

+---------------+-------------------+
|      Part     |      Data         |
+---------------+-------------------+
|  Scheme       | http              |
|  Host         | www.google.com    |
+---------------+-------------------+

如果我们查看一个更复杂的 URL,例如:

“https://bob:bobby@www.lunatech.com:8080/file;p=1?q=2#third”

我们可以提取以下信息:

+-------------------+---------------------+
|        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 parameter
                   Authority

每个部分的保留字符都不同。

对于 HTTP URL,路径片段部分中的空格必须编码为“%20”(不是,绝对不是“+”),而路径片段部分中的“+”字符可以不编码。

现在在查询部分,空格可能被编码为“+”(为了向后兼容:不要尝试在 URI 标准中搜索它)或“%20”,而“+”字符(由于这种歧义) 必须转义为“%2B”。

这意味着“蓝色+浅蓝色”字符串必须在路径和查询部分进行不同的编码:

“http://example.com/blue+light%20blue?blue%2Blight+blue”。

从那里你可以推断,如果没有对 URL 结构的句法意识,编码一个完全构造的 URL 是不可能的。

这归结为:

你应该有%20之前?+之后。

资源

于 2015-04-29T15:36:44.923 回答
28

I would recommend %20.

Are you hard-coding them?

This is not very consistent across languages, though. If I'm not mistaken, in PHP urlencode() treats spaces as + whereas Python's urlencode() treats them as %20.

EDIT:

It seems I'm mistaken. Python's urlencode() (at least in 2.7.2) uses quote_plus() instead of quote() and thus encodes spaces as "+". It seems also that the W3C recommendation is the "+" as per here: http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1

And in fact, you can follow this interesting debate on Python's own issue tracker about what to use to encode spaces: http://bugs.python.org/issue13866.

EDIT #2:

I understand that the most common way of encoding " " is as "+", but just a note, it may be just me, but I find this a bit confusing:

import urllib
print(urllib.urlencode({' ' : '+ '})

>>> '+=%2B+'
于 2009-10-27T23:31:37.297 回答
24

在 URL 的“application/x-www-form-urlencoded”内容类型键值对查询部分中,空格只能编码为“+”。在我看来,这是可以的,而不是必须的。在其余的 URL 中,它被编码为 %20。

在我看来,最好始终将空格编码为 %20,而不是“+”,即使在 URL 的查询部分也是如此,因为 HTML 规范 ( RFC 1866 ) 指定空格字符应编码为“+” " 在 "application/x-www-form-urlencoded" 内容类型键值对中(参见第 8.2.1 段。第 1 小段。)

这种编码表单数据的方式也在后面的 HTML 规范中给出。例如,在 HTML 4.01 Specification 中查找有关 application/x-www-form-urlencoded 的相关段落,等等。

这是 URL 中的示例字符串,其中 HTML 规范允许将空格编码为加号:“http://example.com/over/there?name=foo+bar”。所以,只有在“?”之后,空格才能被加号代替。在其他情况下,空格应编码为 %20。但由于很难正确确定上下文,最好不要将空格编码为“+”。

我建议对除RFC 3986 , p.2.3中定义的“未保留”之外的所有字符进行百分比编码

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

实现取决于您选择的编程语言。

如果您的 URL 包含国家字符,请先将它们编码为 UTF-8,然后对结果进行百分比编码。

于 2016-10-27T19:29:10.377 回答