提问人:mykhal 提问时间:8/14/2010 最后编辑:xnumadmykhal 更新时间:11/17/2023 访问量:52190
分号作为 URL 查询分隔符
Semicolon as URL query separator
问:
尽管强烈建议(W3C 源,通过维基百科)让 Web 服务器支持分号作为 URL 查询项的分隔符(除了 & 号)(在撰写本文时,不再通过维基百科),但似乎并没有普遍遵循。
例如,比较
http://www.google.com/search?q=nemo&oe=UTF-8
http://www.google.com/search?q=nemo;OE=UTF-8
结果。(在后一种情况下,分号是或在撰写本文时被视为普通字符串字符,就好像 url 是:http://www.google.com/search?q=nemo%3Boe=utf-8)
尽管我尝试过的第一个 URL 解析库表现良好:
>>> from urlparse import urlparse, query_qs
>>> url = 'http://www.google.com/search?q=nemo;oe=utf-8'
>>> parse_qs(urlparse(url).query)
{'q': ['nemo'], 'oe': ['utf-8']}
接受分号作为分隔符的现状如何,潜在的问题或一些有趣的注释是什么?(从服务器和客户端的角度来看)
答:
只要你的 HTTP 服务器和服务器端应用程序接受分号作为分隔符,你就应该可以开始了。我看不出任何缺点。正如你所说,W3C 规范站在你这边:
我们建议 HTTP 服务器实现者,特别是 CGI 实现者支持使用 “;” 代替 “&”,以省去作者以这种方式转义 “&” 字符的麻烦。
评论
;
&
&
?q='one;two'&x=1
{"q": "'one;two'", "x": "1"}
{"q": "'one", "two'": null, "x": "1"}
我同意鲍勃·阿曼(Bob Aman)的观点。W3C 规范旨在使锚点超链接与看起来像 GET 请求形式的 URL 一起使用变得更加容易(例如,)。在这种情况下,与号与号与字符实体引用系统发生冲突,字符实体引用都以与号开头(例如,)。因此,W3C 建议 Web 服务器允许使用分号而不是与号作为字段分隔符,以便更轻松地编写这些 URL。但是,此解决方案要求编写者记住,必须用某些东西替换与号,并且 a 是一个同样有效的字段分隔符,即使 Web 浏览器在提交表单时普遍在 URL 中使用与号。可以说,这比记住在这些链接中用 an 替换 & 符号更困难,就像文档其他地方所做的那样。http://www.host.com/?x=1&y=2
"
;
&
更糟糕的是,在所有 Web 服务器都允许使用分号作为字段分隔符之前,URL 编写者只能将此快捷方式用于某些主机,而必须用于其他主机。如果给定主机停止允许分号分隔符,他们还必须稍后更改其代码。这当然比简单地使用 更难,这将永远适用于每台服务器。这反过来又消除了 Web 服务器允许使用分号作为字段分隔符的任何动机。当每个人都已经将 & 符号更改为 而不是 时,何必呢?&
&
&
;
评论
简而言之,HTML 是一团糟(由于它的宽松),使用分号有助于简化这一点。我估计,当我考虑到我发现的复杂性时,使用与号作为分隔符会使整个过程复杂到使用分号作为分隔符的三倍!
我是一名 .NET 程序员,据我所知,.NET 本身不允许使用“;”分隔符,所以我编写了自己的解析和处理方法,因为我看到了使用分号的巨大价值,而不是使用与号作为分隔符的已经有问题的系统。不幸的是,非常受人尊敬的人(如另一个答案中的@Bob Aman)没有看到为什么分号的使用比使用与号要优越得多,而且简单得多的价值。因此,我现在分享几点,以说服其他尚未认识到使用分号的价值的受人尊敬的开发人员:
在 HTML 页面中使用像 '?a=1&b=2' 这样的查询字符串是不正确的(没有先对其进行 HTML 编码),但大多数时候它都可以工作。然而,这只是由于大多数浏览器是宽容的,并且这种宽容可能会导致难以发现的错误,例如,键值对的值在没有正确编码的情况下发布在 HTML 页面 URL 中(在 HTML 源代码中直接作为“?a=1&b=2”)。像 '?who=me+&+you' 这样的 QueryString 也有问题。
我们这些人可能会有偏见,并且可能会整天不同意我们的偏见,因此认识到我们的偏见非常重要。例如,我同意我只是认为用“;”分隔看起来“更干净”。我同意我的“更干净”的观点纯粹是一种偏见。而另一个开发人员可能具有同样相反但同样有效的偏见。因此,我对这一点的偏见并不比相反的偏见更正确。
但是,鉴于分号的公正支持,从长远来看,每个人的生活都更轻松,当考虑到整个画面时,这是无可争议的。简而言之,使用分号确实让每个人的生活更简单,但有一个例外:习惯新事物的一个小障碍。就这样。做出任何改变总是更加困难。但是,与继续使用&的持续困难相比,进行更改的难度相形见绌。
用;作为 QueryString 分隔符使它变得简单得多。与号分隔符正确编码的难度是使用分号的两倍多。(我认为)大多数实现都没有正确编码,因此大多数实现的复杂程度不会增加一倍。但是,跟踪和修复错误会导致生产力下降。在这里,我指出了当 & 为分隔符时正确编码 QueryString 所需的 2 个单独的编码步骤:
- 第 1 步:对查询字符串的键和值进行 URL 编码。
- 第 2 步:在对第 1 步进行 URL 编码后,将键和值(如“a=1&b=2”)连接起来。
- 步骤3:然后HTML在页面的HTML源代码中对整个QueryString进行编码。
因此,为了正确(无错误)的 URL 编码,必须进行两次特殊编码,不仅如此,编码是两种截然不同的不同编码类型。第一个是 URL 编码,第二个是 HTML 编码(用于 HTML 源代码)。如果其中任何一个不正确,那么我可以为你找到一个错误。但是,对于 XML,步骤 3 是不同的。对于 XML,则需要 XML 字符实体编码(几乎相同)。我的观点是,最后的编码取决于 URL 的上下文,无论是在 HTML 网页中,还是在 XML 文档中。
现在有了更简单的分号分隔符,这个过程就像人们所期望的那样:
- 1:URL对键和值进行编码,
- 2:将值连接在一起。(步骤 3 没有编码。
我认为大多数 Web 开发人员会跳过第 3 步,因为浏览器非常宽松。但是,这会导致错误和更多复杂情况,当寻找这些错误时,或者如果这些错误不存在,用户将无法做事,或者编写错误报告等。
实际使用中的另一个复杂情况是使用 C# 和 VB.NET 在源代码中编写 XML 文档标记时。由于 & 必须编码,从字面上看,这确实拖累了我的生产力。额外的步骤 3 也使阅读源代码变得更加困难。因此,这种难以阅读的缺陷不仅适用于 HTML 和 XML,也适用于 C# 和 VB.NET 代码等其他应用程序,因为它们的文档使用 XML 文档。因此,步骤 #3 编码复杂性也扩散到其他应用程序。
所以总而言之,使用 ;因为分隔符很简单,因为使用分号时的(正确)过程是 WUD 通常期望的过程:只需要进行一个编码步骤。
也许这并不太令人困惑。但是所有的混淆或困难都是由于使用了 HTML 编码的分隔字符。因此,“&”是罪魁祸首。分号缓解了所有这些复杂性。
(我要指出的是,我上面的 3 步与 2 步过程通常是大多数应用程序需要多少步骤。但是,对于完全健壮的代码,无论使用哪种分隔符,都需要所有 3 个步骤。但根据我的经验,大多数实现都是草率且不健壮的。因此,使用分号作为查询字符串分隔符将使更多人的生活更轻松,网站和互操作错误更少,如果每个人都采用分号作为默认分号而不是与号。
评论
1999 年的 W3C 建议书已经过时。根据 2014 年 W3C 建议,目前的状态是分号作为参数分隔符现在是非法的:
要解码 application/x-www-form-urlencoded 有效负载,应使用以下算法。[...]此算法的输出是名称-值对的排序列表。[...]
- 设字符串是严格拆分 U+0026 AMPERSAND 字符 (&) 上的字符串有效负载的结果。
换句话说,意味着参数将具有值;而应该导致(尽管在技术上是非法的,因为第二个应该被转义到)。?foo=bar;baz
foo
bar;baz
?foo=bar;baz=sna
foo
bar;baz=sna
=
%3D
评论
;
&
X-Amz-SignedHeaders: content-type;host
上一个:分号作为 URL 查询分隔符
评论