编码空格字符的URL:+或%20?

BC.*_*BC. 681 url url-encoding

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

Joe*_*oey 403

来自维基百科(重点和链接添加):

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

因此,实际的百分比编码使用%20URL中的表单数据是使用的修改形式+.因此,您最有可能只+在查询字符串中的URL中看到?.

  • 所以基本上:GET提交的目标是`http://www.bing.com/search?q = hello + world`和一个名为`http://camera.phor.net/cameralife/folders/的空间资源2012/2012-06%20Pool%20party /` (31认同)
  • @BC:no - `multipart/form-data`使用MIME编码; `application/x-www-form-urlencoded`使用`+`,正确编码的URI使用`%20`. (17认同)
  • "所以你最有可能只在查询字符串中的URL中看到+?" 是轻描淡写.你永远不应该在URL的路径部分看到"+",因为它不会做你期望的(空格). (8认同)
  • 请注意,对于电子邮件链接,您确实需要%2​​0而不是+之后的+.例如,`mailto:support@example.org?subject = I%20need%20help`.如果您尝试使用+,电子邮件将以+ es而不是空格打开. (8认同)
  • 所以+编码技术上是多部分/表格数据编码,而百分比编码是application/x-www-form-urlencoded? (2认同)
  • [Data uris](http://www.ietf.org/rfc/rfc2397.txt)使用与[uris](http://www.ietf.org/rfc/rfc2396.txt)相同的编码.阅读完RFC后,我可以自信地说我不够聪明,无法解读是否允许将空格编码作为+字符.但是,我可以说,如果使用+而不是%20,则数据uri将无法在浏览器中使用. (2认同)
  • 使用加号的问题是,如果您想接受与空格不同的加号,例如 ?search=The A+ School (2认同)

Mat*_*ius 272

这种混淆是因为到目前为止,URL仍然"被打破".

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

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

+---------------+-------------------+
|      Part     |      Data         |
+---------------+-------------------+
|  Scheme       | http              |
|  Host         | www.google.com    |
+---------------+-------------------+
Run Code Online (Sandbox Code Playgroud)

如果我们查看更复杂的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
Run Code Online (Sandbox Code Playgroud)

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

对于HTTP URL,路径片段部分中的空间必须编码为"%20"(不是,绝对不是"+"),而路径片段部分中的"+"字符可以保持未编码状态.

现在在查询部分中,空格可以编码为"+"(为了向后兼容:不尝试在URI标准中搜索它)或"%20"而不是"+"字符(由于这种模糊性)必须逃到"%2B".

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

" http://example.com/blue+light%20blue?blue%2Blight+blue ".

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

这归结为:

你应该在%20之前?+之后.

资源

  • 实际上,我刚刚看了您引用的 LunaTech 博客文章,带回家的消息似乎更像是: **您必须在“?”之前使用 %20 而不是 +,而是在“之后” ?`这只是一个品味问题**。看在上帝的份上,人们总是使用基于百分号的编码,并为更重要的事情腾出一些大脑空间。 (21认同)
  • 哇,伙计。我不得不说 ASCII 图形看起来很酷。 (9认同)
  • >> 在 ? 之前应该有 %20 和 + 在抱歉这个愚蠢的问题之后。我有点知道在“?”之后使用了 hashtag 参数。问号参数。尽管它有些不同,因为使用“#”不会重新加载页面。但是我一直在尝试在“#”主题标签后使用 %20 和 + 符号,但它似乎不起作用。“#”后面需要用哪个? (2认同)

Rui*_*ira 23

我会推荐%20.

你是硬编码吗?

不过,这在语言上并不十分一致.如果我没有记错,在PHP urlencode()把空格作为+,而Python的urlencode()对待他们作为%20.

编辑:

看来我错了.Python urlencode()(至少在2.7.2中)使用quote_plus()而不是quote()将空格编码为"+".似乎W3C的建议是"+",如下所示:http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1

事实上,你可以在Python自己的问题跟踪器上讨论有关使用什么来编码空间的有趣辩论:http://bugs.python.org/issue13866.

编辑#2:

我知道最常见的编码方式是"+",但只是一个注释,它可能只是我,但我发现这有点令人困惑:

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

>>> '+=%2B+'
Run Code Online (Sandbox Code Playgroud)

  • PHP还有`rawurlencode()`,它使用`%20`. (22认同)
  • Python的`urlencode()`将它们视为`+` (3认同)

Dav*_*aro 17

总结一下这里的(有些矛盾的)答案,我认为可以归结为:

| standard      | +   | %20 |
|---------------+-----+-----|
| URL           | no  | yes |
| query string  | yes | yes |
| form params   | yes | no  |
| mailto query  | no  | yes |
Run Code Online (Sandbox Code Playgroud)

所以从历史上看,我认为发生的事情是:

  1. RFC 指定了关于 URL 的形式及其编码方式的非常清晰的标准。在这种情况下,查询只是一个“字符串”,没有规范如何对键/值对进行编码
  2. HTTP 人员提出了如何在表单参数中对键/值对进行编码的标准,并借用了 URL 编码标准,但空格应编码为+.
  3. 网络人员说:很酷,我们有一种方法来编码键/值对,让我们将其放入 URL 查询字符串中

结果:我们最终得到了两种不同的方法来对 URL 中的空格进行编码,具体取决于您所讨论的部分。但它甚至不违反 URL 标准。从 URL 的角度来看,“查询”只是一个黑匣子。如果您想使用百分比编码之外的其他编码:请自行淘汰。

但正如电子邮件示例所示,借用 URL 查询字符串的 form-params 实现可能会出现问题。因此,最终使用 %20 更安全,但可能没有开箱即用的库支持它。

  • @aderchox我指的是这个评论:/sf/ask/114399001/?noredirect=1#comment45499743_1634293。基本上,电子邮件客户端一般不接受 + 编码。感谢您的赞扬,但我对我的回答不满意,因为它包含一些不准确的地方。引入 + 编码的不是“HTTP 人员”,而是 HTML 人员(请参阅 HTML <form> 标记规范)。我计划尽快修复我的答案并提供一些参考。 (2认同)

Max*_*tin 14

空格只能在URL的"application/x-www-form-urlencoded"内容类型键值对查询部分中编码为"+".这是一个MAY,而不是必须.在其余的URL中,它编码为%20.

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

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

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

我建议对所有字符进行百分比编码,但RFC-3986,p.2.3中定义的"无保留"除外

unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
Run Code Online (Sandbox Code Playgroud)

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

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

  • @MaximMasiutin 当你的回答说“这是可以的,而不是必须的”时,你指的是哪个规范?我正在努力寻找一个可以满足这一要求的规范。在 https://www.w3.org/TR/1999/REC-html401-19991224/interact/forms.html#h-17.13.4.1 中,使用“+”(在查询部分)位于“必须”部分内规格。 (3认同)
  • @JosephH-谢谢您的来信。这是我对MAY的看法。我已经编辑了帖子。我的意思是,您qouted的HTML规范定义了“ +”,但是在URL上下文中,适用其他规则,该规则还允许将空格编码为%20。 (2认同)