在URL中,空格应该使用%20还是+进行编码?

148

在URL中,我应该使用%20还是+对空格进行编码?例如,在下面的示例中,哪一个是正确的?

www.mydomain.com?type=xbox%20360
www.mydomain.com?type=xbox+360

我们公司倾向于前者,但是使用Java方法URLEncoder.encode(String, String)并使用"xbox 360"(和"UTF-8"返回后者

那么,这两者有什么区别呢?


4
为了帮助.NET开发者理解:HttpUtility.UrlPathEncode使用'%20',HttpUtility.UrlEncode使用'+'。来源:http://msdn.microsoft.com/en-us/library/system.web.httputility.urlpathencode(v=vs.110).aspx - CodeToad
6
@MetaByter,我认为在技术上更正确的表达方式是:“在URL中,我应该使用%20还是+来编码空格在URL的查询部分?”,因为虽然您展示的示例仅在查询部分包含空格,但并不清楚所有读者都知道答案取决于哪个部分。或者,您可以这样表达问题:“在下面的具体URL示例中,我应该编码…” - Matthew
6个回答

136

表单数据(GET或POST)通常编码为application/x-www-form-urlencoded:这指定了空格的表示方式是+

URL编码遵循RFC 1738,其中指定空格的表示方式是%20

理论上,在?之前应该使用%20,之后应该使用+

example.com/foo%20bar?foo+bar

12
除了电子邮件链接外,因为在问号后使用+es将导致电子邮件打开时仍带有+es。因此: mailto:support@example.org?subject=I%20need%20help - Sygmoral

57
根据W3C(官方来源),查询字符串中的空格字符(仅限查询字符串)可以编码为“%20”或“+”。从“推荐”下的“查询字符串”部分:
引用: 在查询字符串中,加号被保留为空格的速记符号。因此,必须编码真正的加号。这种方法被用于使查询URI更容易在不允许空格的系统中传递。
根据RFC2396第3.4节,这是有关URI的官方规范,"查询"组件是依赖于URL的:

3.4. Query Component The query component is a string of information to be interpreted by the resource.

   query         = *uric

Within a query component, the characters ";", "/", "?", ":", "@", "&", "=", "+", ",", and "$" are reserved.

因此,如果其他软件无法接受查询字符串中包含空格的URL编码为"+"字符,则存在错误。
至于您问题的第三部分,一种(虽然略显丑陋)修复URLEncoder.encode()输出的方法是在返回值上call replaceAll("\\+","%20")

不要使用URLEncoder编码为application/x-www-form-urlencoded,而应该使用java.net.URI进行编码,它可以进行真正的百分比编码。 - Su Zhang

24

这种困惑是因为到今天为止URL仍然“破碎”。

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

我们可以提取关于 "http://www.google.com" URL 的详细信息:

+---------------+-------------------+   
|      Part     |      Data         |   
+---------------+-------------------+   
|  Scheme       | http              |   
|  Host address | 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 address     | www.lunatech.com    |
|  Port             | 8080                |
|  Path             | /file               |
|  Path parameters  | p=1                 |
|  Query parameters | q=2                 |
|  Fragment         | third               |
+-------------------+---------------------+

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

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

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

这意味着“blue+light blue”字符串必须在路径和查询部分中以不同的方式进行编码: "http://example.com/blue+light%20blue?blue%2Blight+blue"。从那里 您可以推断出,在没有URL结构的语法意识的情况下编码完全构造的URL是不可能的。

简而言之:

你应该在?之前加上%20,并在+之后添加

来源


源链接 404,已移动到 https://blog.lunatech.com/posts/2009-02-03-what-every-web-developer-must-know-about-url-encoding ,但这个链接中的“绝对不是“+””部分被破坏了;因此最好通过 wayback machine 使用原始链接:https://web.archive.org/web/20151218094722/http://blog.lunatech.com/2009/02/03/what-every-web-developer-must-know-about-url-encoding。 - Beni Cherniavsky-Paskin

8

这并不重要,就像你把字母A编码为%41一样。

但是,如果你处理的系统无法识别其中一种形式,似乎你只能按照它期望的方式提供数据,而不管“规范”中说了什么。


5
您可以使用“+”或“-”,但由于“+”更易于阅读,大多数人选择使用它。

0

在编码查询值时,使用表单、加号或百分号-20都是有效的;然而,由于互联网的带宽并不是无限的,你应该使用加号,因为它少了两个字节。


11
过早的优化是万恶之源。这意味着在了解实际需要之前就过度优化代码或系统的性能可能会导致不必要的复杂性和问题。因此,应该先专注于正确性和可维护性,然后再考虑优化。 - Kamafeather
1
因为它让我笑了,所以我点了赞。 - Caleb
我认为使用加号的更好理由是,它比%20更容易阅读。至少对我来说是这样。 - rooby

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接