分号作为URL查询分隔符

时间:2010-08-14 01:44:23

标签: http parsing url webserver query-string

虽然强烈建议(W3C source,通过Wikipedia)网络服务器支持分号作为URL查询项的分隔符(除了&符号)之外,似乎一般都没有遵循

例如,比较

http://www.google.com/search?q=nemo&oe=utf-8

http://www.google.com/search?q=nemo;oe=utf-8

结果。 (在后一种情况下,分号是,或者在撰写本文时,被视为普通字符串字符,就像网址是: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']}

接受分号作为分隔符的当前状态是什么,哪些是潜在的问题或一些有趣的注释? (从服务器和客户端的角度来看)

4 个答案:

答案 0 :(得分:19)

W3C Recommendation from 1999已过时。根据{{​​3}},当前状态是分号现在是非法作为参数分隔符:

  

要解码application / x-www-form-urlencoded有效负载,应使用以下算法。 [...]此算法的输出是名称 - 值对的排序列表。 [...]

     
      
  1. 让字符串成为在U + 0026 AMPERSAND字符(&)上严格拆分字符串有效负载的结果。
  2.   

换句话说,?foo=bar;baz表示参数foo的值为bar;baz;而?foo=bar;baz=sna应该导致foobar;baz=sna(虽然技术上非法,因为第二个=应该转义为%3D)。

答案 1 :(得分:17)

只要你的HTTP服务器和你的服务器端应用程序接受分号作为分隔符,你就应该好了。我看不出任何弊端。如你所说,W3C spec is on your side

  

我们建议HTTP服务器实现者,特别是CGI实现者支持使用“;”取代“&”为作者省去逃避“&”的麻烦这种方式的人物。

答案 2 :(得分:5)

我同意鲍勃阿曼的观点。 W3C规范旨在使锚点超链接更容易使用看起来像表单GET请求的URL(例如http://www.host.com/?x=1&y=2)。在这种情况下,&符号与系统冲突,用于字符实体引用,所有这些都以&符号开头(例如,")。因此,W3C建议Web服务器允许使用分号作为字段分隔符而不是&符号,以便更容易编写这些URL。但是这个解决方案要求编写者记住,&符号必须被某些内容替换,并且;是一个同样有效的字段分隔符,即使Web浏览器在提交表单时通常在URL中使用&符号。记住在这些链接中用&替换&符号可能会更加困难,正如文档中其他地方所做的那样。

更糟糕的是,在所有Web服务器都允许使用分号作为字段分隔符之前,URL编写者只能对某些主机使用此快捷方式,并且必须对其他主机使用&。如果给定主机停止允许使用分号分隔符,他们还必须稍后更改其代码。这肯定比简单地使用&更难,这将永远适用于每个服务器。这反过来又消除了Web服务器允许分号作为字段分隔符的任何动机。当每个人都已将&符更改为&而不是;时,为什么还要费心呢?

答案 3 :(得分:2)

简而言之,HTML是一个很大的混乱(由于它的宽大),使用分号有助于简化这一点。我估计当我考虑到我发现的并发症时,使用&符号作为分隔符会使整个过程变得比使用分号代替分隔符复杂三倍!

我是.NET程序员,据我所知,.NET 本身就允许&#39 ;;'分隔符,所以我编写了自己的解析和处理方法,因为我看到了使用分号的巨大价值,而不是使用&符号作为分隔符的已经存在问题的系统。不幸的是,非常受人尊敬的人(比如@Bob Aman在另一个答案中)并没有看到为什么分号使用远比使用&符更简单和更简单的价值。所以我现在分享一些观点,或许说服其他可敬的开发人员,他们不会认识到使用分号的价值:

使用类似'?a = 1& b = 2'的查询字符串在HTML页面中是不合适的(没有HTML编码首先),但大多数时候它的工作原理。然而,这仅仅是由于大多数浏览器都是容忍的,并且当例如键值对的值在没有正确编码的情况下在HTML页面URL中发布时(例如&#),容差可能导致难以发现的错误。 39; HTML源代码中的?a = 1& b = 2'一个QueryString,比如'?who = me +& + you'也是有问题的。

我们的人可能会有偏见并且可能整天都不同意我们的偏见,所以认识到我们的偏见非常重要。例如,我同意我只是想与';'看起来更干净'我同意我的清洁工'意见纯粹是一种偏见。而另一位开发人员可能会产生同样相反且同样有效的偏见。因此,我对这一点的偏见并不比相反的偏见更正确。

但是考虑到分号的公正支持,从长远来看,每个人的生活都会变得更容易,当考虑到整个画面时,不能正确地提出异议。简而言之,使用分号确实可以使每个人的生活变得更简单,但有一个例外:习惯于新事物的小障碍。这就是全部。做任何改变总是比较困难。但与继续使用&。

的持续困难相比,改变的难度相形见绌

使用;作为QueryString分隔符使其更简单。 正确编码的&符号比使用分号的两倍多。 (我认为)大多数实现都没有正确编码,因此大多数实现都不是复杂的两倍。但随后追踪并修复错误会导致生产力下降。在这里,我指出了正确编码QueryString所需的2个单独的编码步骤。是分隔符:

  • 步骤1:URL编码查询字符串的键和值。
  • 步骤2:连接键和值,例如&a; 1 =& b = 2'在从步骤1开始进行URL编码之后。
  • 步骤3:然后HTML对页面的HTML源代码中的整个QueryString进行编码。

因此,对于正确(无错误)的URL编码,必须进行两次特殊编码,而不仅仅是这样,但编码是两种截然不同的编码类型。第一个是URL编码,第二个是HTML编码(用于HTML源代码)。如果其中任何一个不正确,那么我可以找到你的错误。但是第3步与XML不同。对于XML,则需要XML字符实体编码(几乎相同)。我的观点是,最后一次编码取决于URL的上下文,无论是在HTML网页中还是在XML文档中。

现在使用更简单的分号分隔符,这个过程就像人们期望的那样:

  • 1:URL对键和值进行编码,
  • 2:将值连接在一起。 (没有第3步的编码。)

我认为大多数Web开发人员都会跳过第3步,因为浏览器非常宽松。但是,如果找不到这些错误,或者如果这些错误不存在,或者编写错误报告等,那么这会导致错误和更复杂的问题。

实际使用中的另一个复杂因素是在C#和VB.NET中的源代码中编写XML文档标记时。从&必须进行编码,从字面上看,这对我的工作效率来说是一个真正的拖累。额外的第3步也使得阅读源代码变得更加困难。因此,这种难以读取的缺陷不仅适用于HTML和XML,还适用于其他应用程序,如C#和VB.NET代码,因为它们的文档使用XML文档。因此,步骤#3编码复杂性也扩散到其他应用程序。

总之,使用;作为分隔符很简单,因为使用分号时的(正确)过程是人们通常期望过程的方式:只需要进行一步编码。

也许这并不太令人困惑。但所有的困惑或困难都是由于使用了一种混淆为HTML编码的分离字符。因此'&'是罪魁祸首。分号可以解除所有复杂问题。