ChatGPT解决这个技术问题 Extra ChatGPT

何时应将空格编码为加号 (+) 或 %20? [复制]

这个问题在这里已经有了答案: URL encoding the space character: + or %20? (5 个回答) 8 个月前关闭。

有时空格的 URL 编码为 + 符号,有时则为 %20。有什么区别,为什么会发生这种情况?


P
Peter Mortensen

+ 表示 application/x-www-form-urlencoded 内容中的空格only,例如 URL 的查询部分:

http://www.example.com/path/foo+bar/path?query+name=query+value

在这个 URL 中,参数名称是带有空格的 query name,值是带有空格的 query value,但路径中的文件夹名称实际上是 foo+bar不是 foo bar

%20 是在任一上下文中编码空间的有效方法。因此,如果您需要对字符串进行 URL 编码以包含在 URL 的一部分中,将空格替换为 %20 并将加号替换为 %2B 总是安全的。这就是,例如,encodeURIComponent() 在 JavaScript 中所做的。不幸的是,这不是 urlencode 在 PHP 中所做的(rawurlencode 更安全)。

也可以看看

HTML 4.01 Specification application/x-www-form-urlencoded


真的我很困惑,我的问题是,浏览器什么时候做第一种形式,什么时候做第二种形式?
浏览器将从带有 <input name="query name" value="query value"> 的表单创建一个 query+name=query+value 参数。它不会从表单创建 query%20name,但使用它是完全安全的,例如。如果您要自己为 XMLHttpRequest 提交表单。如果您的 URL 中有一个空格,例如 <a href="http://www.example.com/foo bar/">,那么浏览器会将其编码为 %20 以便您纠正错误,但最好不要依赖它。
javascript 上的什么函数使 foo bar 变为 foo+bar
@Sisir:没有一个可以进行 URL-form-encoding 的 JS 函数。如果你真的需要+,你自然可以做encodeURIComponent(s).replace(/%20/g, '+')
这是一个非常非常令人困惑的表单编码的例子。它与 URL 无关。
P
Peter Mortensen

所以,这里的答案都有点不完整。在 RFC 3986 中明确定义了使用“%20”对 URL 中的空格进行编码,它定义了 URI 的构建方式。本规范中没有提到使用 '+' 来编码空格 - 如果您仅按照本规范进行,则必须将空格编码为 '%20'。

提到使用“+”编码空间来自 HTML 规范的各种化身 - 特别是在描述内容类型“application/x-www-form-urlencoded”的部分中。这用于发布表单数据。

现在,HTML 2.0 规范 (RFC 1866) 在第 8.2.2 节中明确指出,GET 请求的 URL 字符串的 query 部分应编码为 'application/x -www-form-urlencoded'。从理论上讲,这表明在查询字符串的 URL 中使用“+”是合法的(在“?”之后)。

但是……真的吗?请记住,HTML 本身就是一种内容规范,带有查询字符串的 URL 可以用于 HTML 以外的内容。此外,虽然 HTML 规范的更高版本继续在 'application/x-www-form-urlencoded' 内容中将 '+' 定义为合法,但它们完全省略了将 GET 请求查询字符串定义为该类型的部分。事实上,在 HTML 2.0 规范之后的任何内容中都没有提及查询字符串编码。

这给我们留下了一个问题——它有效吗?当然,有很多遗留代码支持查询字符串中的“+”,还有很多生成它的代码。因此,如果您使用“+”,您将不会中断。 (事实上,我最近对此进行了所有研究,因为我发现了一个主要站点未能在 GET 查询中接受“%20”作为空格。他们实际上未能解码任何 百分比编码字符。因此您使用的服务也可能是相关的。)

但是从纯粹的规范阅读来看,如果没有将 HTML 2.0 规范中的语言延续到更高版本中,则 URL 完全被 RFC 3986 覆盖,这意味着应该将空格转换为 '%20'。如果您请求的不是 HTML 文档,那肯定是这种情况。


为了增加您的答案,Chrome 默认将 URL 中的空格编码为 %20 (<a href="?q=a b">),但是当您发送表单时,它使用 + 符号。您可以通过显式使用 + 符号 (<a href="?q=a+b">) 或使用 XMLHTTPRequest 发送表单来覆盖它。
真的很难理解添加 URLSearchParams developers.google.com/web/updates/2016/01/urlsearchparams 的目的,它以某种传统方式工作(将 SPACE 序列化为“+”)。 IE11 甚至不支持它!
c
cerberos

http://www.example.com/some/path/to/resource?param1=value1

问号之前的部分必须使用 % 编码(因此 %20 表示空格),问号之后您可以使用 %20+ 表示空格。如果在问号后需要实际的 +,请使用 %2B


@DaveVandenEynde 为什么不呢?
因为这是错误的。它是旧的 application/x-www-form-urlencoded 媒体类型的一部分,不适用于 URL。此外,decodeURIComponent 不会对其进行解码。
是的,它可能是从 RFC 1630 复制过来的,从来没有真正成为标准。 tools.ietf.org/html/rfc3986 是标准(针对 IPv6 或其他内容再次更新)。当然浏览器仍然“支持”它,但这意味着什么?读取查询字符串并对其进行解码的是服务器或客户端代码,而不是浏览器。浏览器只是简单地来回传递它,因为 + 是一个保留字符,它会被浏览器保留。
Google 在其搜索网址 (google.com/#q=perl+equivalent+to+php+urlencode+spaces+as+%2B) 中使用 + 号表示空格。
仅供参考:默认情况下,Rails 还使用 + 解码空格({ foo: 'bar bar'}.to_query => foo=bar+bar
P
Peter Mortensen

出于兼容性原因,最好始终将空格编码为“%20”,而不是“+”。

它是 RFC 1866(HTML 2.0 规范),它指定在“application/x-www-form-urlencoded”内容类型键值对中空格字符应编码为“+”。 (见第 8.2.1 段第 1 小段)。这种编码表单数据的方式在后面的 HTML 规范中也有给出,寻找有关 application/x-www-form-urlencoded 的相关段落。

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

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

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

您可能希望将空格编码为“+”(一个字节)而不是“%20”(三个字节)的唯一情况是您确定如何解释上下文,并且查询字符串的大小为精华。


在 .Net Framework 中 UrlEncode 在 QueryString 中使用“+”,但在现代 .Net Core 中使用 %20
@MiFreidgeimSO-stopbeingevil 感谢您告知我们。似乎现代的 .Net Core 决定更加一致和兼容。
P
Peter Mortensen

有什么不同?查看其他答案。

我们什么时候应该使用 + 而不是 %20?如果出于某种原因您想让 URL 查询字符串 (?.....) 或哈希片段 (#....) 更具可读性,请使用 +。示例:您实际上可以阅读以下内容:

https://www.google.se/#q=google+doesn%27t+encode+:+and+uses+%2B+instead+of+spaces (%2B = +)

但以下内容更难阅读(至少对我而言):

https://www.google.se/#q=google%20doesn%27t%20oops%20:%20%20this%20text%20%2B%20is%20different%20spaces

我认为 + 不太可能破坏任何东西,因为 Google 使用 +(请参阅上面的第一个链接)并且他们可能已经考虑过这一点。我将自己使用 + 只是因为 readable + Google 认为它还可以。


我说“可读性”论点是“+”的最佳辩护。 “谷歌做到了”的说法是错误的en.wikipedia.org/wiki/Argument_from_authority
@FlipMcF 来自权威的错误论证 Wikipedia 页面是关于“当在其专业领域之外的主题上引用权威时,或者当引用的权威不是真正的专家时”——然而,我认为计算机、HTTP 和 URL编码是谷歌专业领域内的东西。
@FlipMcF 在这种情况下,引用 google 的行为是在 URL 中使用“+”的有效参数。并不是说 google 是权威,而是 google 可能是最大的互联网公司,如果他们以某种方式做某事,浏览器不太可能有朝一日决定停止支持这种做法。此外,谷歌浏览器是份额最高的浏览器之一,它们将支持谷歌想要的任何东西。总而言之,我想说在可预见的将来,没有人会因为使用“+”而不是“%20”而遇到困难。
我很想在其他地方继续这个论点,在那里可以呼吁大众拒绝承认对权威的呼吁。至少我们都可以同意一件事:'+' 优于 '%20'
实际上,带有 %20 的 URL 更容易阅读,因为如果您将鼠标光标移到链接上,(桌面)浏览器会在窗口底部显示解码的 URL。加号显示不变。