【问题标题】:When should space be encoded to plus (+) or %20? [duplicate]何时应将空格编码为加号 (+) 或 %20? [复制]
【发布时间】:2011-02-10 08:03:38
【问题描述】:

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

【问题讨论】:

    标签: urlencode


    【解决方案1】:

    + 表示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不是@ 987654330@.

    %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:没有 JS 函数可以进行 URL-form-encoding。如果你真的需要+,你自然可以做encodeURIComponent(s).replace(/%20/g, '+')
    • 这是一个非常非常令人困惑的表单urlencoded示例。它与 URL 无关。
    【解决方案2】:

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

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

    现在,HTML 2.0 规范(RFC 1866) 在第 8.2.2 节中明确指出,GET 请求的 URL 字符串的 query 部分应编码为 '应用程序/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 甚至都不支持!
    【解决方案3】:

    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
    【解决方案4】:

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

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

    以下是 RFC 1866 允许将空格编码为加号的 URL 字符串示例:“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 决定更加一致和兼容。
    【解决方案5】:

    有什么区别?查看其他答案。

    我们什么时候应该使用+ 而不是%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 认为没问题。

    【讨论】:

    • 我说“可读性”参数是“+”的最佳防御。 “谷歌做到了”的说法是错误的en.wikipedia.org/wiki/Argument_from_authority
    • @FlipMcF 错误的权威论据维基百科页面是关于“当一个权威被引用的主题在他们的专业领域之外或当引用的权威是不是真正的专家”——不过,我认为计算机、HTTP 和 URL 编码是 Google 的专业领域内的东西。
    • @FlipMcF 在这种情况下,引用 google 的行为是在 URL 中使用“+”的有效参数。并不是说 google 是权威,而是说 google 可能是最大的互联网公司,如果他们以某种方式做某事,浏览器不太可能有朝一日决定停止支持这种做法。此外,谷歌浏览器是份额最高的浏览器之一,它们将支持谷歌想要的任何东西。总而言之,我想说,在可预见的将来,没有人会因为这个而使用“+”而不是“%20”。
    • 我很想在其他地方继续这个论点,在这个地方可以呼吁大众拒绝承认对权威的呼吁。至少我们都可以同意一件事:'+' 优于 '%20'
    • 实际上带有 %20 的 URL 更容易阅读,因为如果您将鼠标光标移到链接上,(桌面)浏览器会在窗口底部显示解码后的 URL。加号显示不变。
    猜你喜欢
    • 2022-01-25
    • 2010-11-15
    • 2010-12-10
    • 1970-01-01
    • 1970-01-01
    • 2013-08-21
    相关资源
    最近更新 更多