URL 中的空格何时编码为+
,何时编码为%20
?
4 回答
来自维基百科(强调和链接添加):
当提交已输入 HTML 表单的数据时,表单字段名称和值将被编码并使用方法 GET 或 POST 或过去通过电子邮件在 HTTP 请求消息中发送到服务器。默认使用的编码基于通用 URI 百分比编码规则的早期版本,并进行了许多修改,例如换行规范化和用“+”而不是“%20”替换空格。以这种方式编码的数据的 MIME 类型是 application/x-www-form-urlencoded,目前在 HTML 和 XForms 规范中定义(仍然以非常过时的方式)。
因此,真正的百分比编码使用%20
,而 URL 中的表单数据是使用+
. 因此,您很可能只+
在查询字符串中的 URL 中看到?
.
这种混淆是因为 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
之前?
和+
之后。
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+'
在 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,然后对结果进行百分比编码。