ChatGPT解决这个技术问题 Extra ChatGPT

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

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


T
Timothy Jones

来自 Wikipedia(添加了重点和链接):

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

因此,real 百分比编码使用 %20,而 URL 中的表单数据是使用 + 的修改形式。因此,您很可能只会在 ? 之后的查询字符串中的 URL 中看到 +


所以 + 编码在技术上是 multipart/form-data 编码,而百分比编码是 application/x-www-form-urlencoded?
@BC:否 - multipart/form-data 使用 MIME 编码; application/x-www-form-urlencoded 使用 +,正确编码的 URI 使用 %20
“所以你很可能只在 ? 之后的查询字符串中的 URL 中看到 + ?”是轻描淡写。你不应该在 URL 的路径部分看到“+”,因为它不会做你期望的(空格)。
所以基本上: GET 提交的目标是 http://www.bing.com/search?q=hello+world 和名称中有空格的资源 http://camera.phor.net/cameralife/folders/2012/2012-06%20Pool%20party/
请注意,对于电子邮件链接,您确实需要 %20 而不是 ? 之后的 +。例如,mailto:support@example.org?subject=I%20need%20help。如果您尝试使用 +,电子邮件将使用 +es 而不是空格打开。
P
Peter Mortensen

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

a blog post

以“http://www.google.com”为例。这是一个网址。 URL 是统一资源定位器,实际上是指向网页的指针(在大多数情况下)。自 1994 年第一个规范以来,URL 实际上具有非常明确的结构。我们可以提取有关“http://www.google.com” URL 的详细信息:+------------- --+--------------------------------+ |零件 |数据 | +---------------+-------------------+ |方案 | http | |主持人 | www.google.com | +---------------+-------------------+ 如果我们查看更复杂的 URL,例如:“https ://bob:bobby@www.lunatech.com:8080/file;p=1?q=2#third" 我们可以提取以下信息:+--------------- --+------------+ |零件 |数据 | +-----------------+---------------------+ |方案 | https | |用户 |鲍勃 | |密码 |鲍比 | |主持人 | www.lunatech.com | |港口 | 8080 | |路径 | /文件;p=1 | |路径参数 | p=1 | |查询 | q=2 | |片段 |第三| +-----------------+---------------------+ https://bob:bobby @www.lunatech.com:8080/file;p=1?q=2#third \___/ \_/ \___/ \______________/ \__/\_______/ \_/ \___/ | | | | | | \_/ | |方案用户密码主机端口路径| |片段\_____________________________/ |查询 |路径参数 权限 每个部分的保留字符不同。对于 HTTP URL,路径片段部分中的空格必须编码为“%20”(不是,绝对不是“+”),而路径片段部分中的“+”字符可以不编码。现在在查询部分,空格可以编码为“+”(为了向后兼容:不要尝试在 URI 标准中搜索它)或“%20”,而“+”字符(由于这种歧义) 必须转义为“%2B”。这意味着“蓝色+浅蓝色”字符串必须在路径和查询部分中进行不同的编码:“http://example.com/blue+light%20blue?blue%2Blight+blue”。从那里你可以推断,如果没有对 URL 结构的句法意识,编码一个完全构造的 URL 是不可能的。

这归结为:

您应该在 ? 之前和 + 之后有 %20

Source


>> 你应该在 ? 之前有 %20和 + 在对不起这个愚蠢的问题之后。我知道在“?”之后使用了主题标签参数。问号参数。尽管它有所不同,因为使用“#”不会重新加载页面。但是我一直在尝试在“#”标签之后使用 %20 和 + 符号,但它似乎不起作用。 “#”后面需要用哪一个?
@Philcyb 你可能想读这个en.wikipedia.org/wiki/Percent-encoding
查询部分是否真的有“官方”标准?我认为基本上那部分是特定于应用程序的。 99.99% 的应用程序使用 key1=value1&key1=value2,其中键和值按照 encodeURIComponent 遵循的任何规则进行编码,但 AFAIK 查询部分的内容完全 100% 取决于应用程序。其他然后它只进入第一个 # 没有官方编码。
实际上,我只是看了一下 LunaTech 博客文章,您好心地引用了这篇文章,并且带回家的消息似乎更像是:您必须在 ? 之前使用 %20 而不是 +,但在? 这只是口味问题。看在上帝的份上,人们,总是使用基于百分号的编码,并为更重要的东西腾出一些大脑空间。
哇伙计。我不得不说 ASCII 图形看起来很酷。
t
the Tin Man

我会推荐%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+'

不是硬编码。试图从美学的角度来确定我的包含空格的网址会是什么样子。
嗨,我也很困惑,当用户提交 html 表单时,表单如何编码空间?与哪个角色?结果是否取决于浏览器?
Java 中的 URLEncoder.encode() 方法也将其转换为 +
然后出现了关于如何处理 POST 请求正文中的编码的问题:“Content-Type: application/x-www-form-urlencoded”,其中参数的形式为“a=b&c=d”,但根本不在 URL 中,只是“文档”的正文。他们把这个问题搞得一团糟,很难找到明确的答案。
Perls uri_escape() 将它们视为 %20
M
Maxim Masiutin

在 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 中定义的“未保留”之外的所有字符进行百分比编码,第 2.3 页

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

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

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


如果请求的资源不是 HTML,为什么还要关心 HTML 规范?我在一些不响应 HTML 的 Web API 中看到了“+”,例如您请求 pdf。我认为他们不使用“%20”是错误的。
@TheincredibleJan,我同意你的看法。这就是我的回复。
@MaximMasiutin 当您的回答说“这是可能的,而不是必须的”时,您指的是哪个规范?我正在努力寻找一个尽可能多的规范。在 w3.org/TR/1999/REC-html401-19991224/interact/… 中使用“+”(在查询部分)属于规范的“必须”部分。
@JosephH - 谢谢你的笔记。这是我对 MAY 的个人看法。我已经编辑了帖子。我的意思是您引用的 HTML 规范定义了“+”,但在 URL 上下文中,其他规则适用,这些规则也允许将空格编码为 %20。
D
David Ongaro

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

| standard      | +   | %20 |
|---------------+-----+-----|
| URL           | no  | yes |
| query string  | yes | yes |
| form params   | yes | no  |
| mailto query  | no  | yes |

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

RFC 为 URL 的形式及其编码方式指定了一个非常明确的标准。在这种情况下,查询只是一个“字符串”,没有规范应该如何编码键/值对 HTTP 家伙提出了如何在表单参数中编码键/值对的标准,并从 URL 中借用编码标准,除了空格应该编码为+。网友说:很酷,我们有一种编码键/值对的方法,让我们把它放到 URL 查询字符串中

结果:我们最终得到了两种不同的方法来编码 URL 中的空格,具体取决于您正在谈论的部分。但它甚至不违反 URL 标准。从 URL 的角度来看,“查询”只是一个黑盒。如果你想使用除了百分比编码之外的其他编码:把自己搞砸。

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