可以在查询字符串之前跳过斜杠吗?

时间:2009-10-24 05:29:52

标签: url query-string

在追加查询字符串时总是跳过尾部斜杠是否安全?

也就是说,我可以使用

http://example.com?querystring

而不是:

http://example.com/?querystring

?我使用的所有webhost都支持这个,但是可以安全地假设所有服务器环境都支持这种方法吗?它是标准的吗?

5 个答案:

答案 0 :(得分:47)

否。跳过斜杠是不正确的。 可能使用现代浏览器:但是,这并不能使其正确。

RFC1738 - URLRFC2396 - URI

RFC1738的格式(我在此处排除了架构格式):

  
    

//<使用者>:其中密码> @<宿主GT;:其中端口> /< URL路径>

  

接下来要注意:

  
    

...主机(或端口)与url-path之间的“/”不是url-path的一部分。

  

在这种情况下,“?” 的一部分

  
    

...取决于所使用的方案,以及它的解释方式。

  

另请注意,根据规范,省略“/ url-path”完全有效 - 请注意,在这种情况下,“/”已明确包含在内。

因此,“foo.com?bar”无效,因为在url-path之前没有“/”。

答案 1 :(得分:47)

作为现代规范的问题, ,允许跳过斜杠,与此处accepted answer声称的相反。

虽然接受的答案正确引用了RFC 1738(20多年前发布!),但它错误地声称RFC 2396(1998年发布)需要斜杠,而忽略了那些规范的两个反过来被RFC 3986淘汰,2005年发布(仍然是在接受的答案写入之前几年),最近由WhatWG URL Standard淘汰,两者都允许省略斜杠。

让我们依次从最早到最晚考虑这些规范:

RFC 1738: Uniform Resource Locators (URL)(1994年发布)

隐式要求斜杠包含在specifying that it may be omitted if the URL contains neither a path nor a query string中(此处称为searchpart)。下面的结合是我的:

  

HTTP URL采用以下形式:

http://<host>:<port>/<path>?<searchpart>
     

其中<host><port>Section 3.1中所述。如果:<port>   省略,端口默认为80.没有用户名或密码   允许。 <path>是HTTP选择器,<searchpart>是查询   串。 <path>是可选的,<searchpart>及其<path>也是可选的   在&#34;?&#34;。 如果<searchpart>opaque_part都不存在,则&#34; /&#34;   也可以省略。

RFC 2396: Uniform Resource Identifiers (URI): Generic Syntax (1998年发布;&#34;更新&#34; RFC 1738)

这里省略斜杠是可以接受的。这个RFC将一些奇怪的URL语法合法化,这些语法在方案之后没有双斜杠,但是如果我们忽略了这些语法(它们是规范中absoluteURI的那些absoluteURI = scheme ":" ( hier_part | opaque_part ) { {3}})并坚持使用包含主机的网址,然后我们发现hier_part定义如下...

hier_part     = ( net_path | abs_path ) [ "?" query ]

并且net_path看起来像这样:

net_path      = "//" authority [ abs_path ]

并且abs_path看起来像这样:

abs_path

其中scheme://authority?query又定义为以斜杠开头。请注意,上面语法中的URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] hier-part = "//" authority path-abempty / path-absolute / path-rootless / path-empty 可选 - 这意味着path-abempty形式的网址完全合法。

附录BNF暗示了这一变化的动机:

  

问号&#34;?&#34;字符已从允许的集合中删除      自测试以来,权限组件中userinfo的字符      表明许多应用程序将其视为保留用于分离      从URI的其余部分查询组件。

换句话说 - 现实世界中的代码假设URL中的第一个问号在任何地方都标记了查询字符串的开头,因此规范已经过实际更新以符合现实。

G.2. Modifications from both RFC 1738 and RFC 1808(2005年发布;&#34;废弃&#34; RFC 2396)

同样,允许省略斜杠。规范通过说&#34;路径&#34;来表达这一点。在包含权限(主机)的每个URI中都是必需的,并且该路径必须 以斜杠开头或不包含任何字符:

  

RFC 3986: Uniform Resource Identifier (URI): Generic Syntax

     

通用URI语法由层次结构序列组成      组件称为方案,权限,路径,查询和      片段。

path-abempty  = *( "/" segment )
     

方案和路径组件是必需的,尽管路径可能是      空(没有字符)。当权威存在时,路径必须      要么为空,要么以斜杠(&#34; /&#34;)开头。

为了完整起见,请注意file后来定义为:

:

这确实允许它不包含任何字符。

3. Syntax Components由WhatWG(主动维护下的生活标准,最初创建于2012年,目标是废弃RFC 3986)

同样,省略斜线是可以接受的,虽然这次我们没有看BNF但需要阅读大量的散文。

URL Standard告诉我们:

  

Section 4.3必须是以下

之一            

任意后跟&#34;?&#34;和URL查询字符串。

由于HTTP和HTTPS为scheme-relative-file-URL string,因此任何HTTP或HTTPS网址都必须满足这三个选项中的第一个 - 即//:后跟special schemes ,其中:

  

必须是&#34; ?&#34;,然后是scheme-relative-special-URL string,可选地后跟&#34; http://example.com?query&#34;和valid host string,可选地后跟URL-port string

path-absolute-URL string被定义为以斜杠开头,但在上面的绝对URL字符串的定义中是显式可选的;因此,允许直接从主持人直接进入&#34; {{1}}&#34;和查询字符串,因此{{1}}之类的网址是合法的。

当然,这些都不能保证每个Web服务器或HTTP库都接受这样的URL,也不会将它们视为在语义上等同于包含斜杠的URL。但就 spec 而言,跳过斜杠是完全合法的。

答案 2 :(得分:4)

假设 安全。 Web服务器和自包含Web应用程序通常会检查请求中提供的URL,但无法保证它们会将/abc视为等于/abc/。 Web服务器和独立的Web应用程序可以使用从URL中收集的信息任何他们喜欢的,并且它不一定是您所期望的。您必须找出相关特定网址的约定。

当然,请注意,大多数Web服务器和Web应用程序框架都在努力接受各种输入并适当地处理它们。因此,在大多数情况下,Web服务器或自包含Web应用程序会将/abc视为/abc/。但请记住,因为服务器可以通过路径做任何喜欢的事情,这只是一个通用的观察,可能有很多例外。

答案 3 :(得分:4)

在研究此问题后,我发现了一些更多信息,以此来添加接受的答案:

http://tools.ietf.org/html/rfc2396

  

权限组件前面有一个双斜杠“//”,并由下一个斜杠“/”,问号“?”或URI的末尾终止。在权限组件中,保留字符“;”,“:”,“@”,“?”和“/”

根据此声明,问号应指明权限组件的结尾,有或没有斜杠。

http://tools.ietf.org/html/rfc1738(已替换代码)

  

{path}是可选的,{searchpart}及其前面的“?”也是可选的。如果{path}和{searchpart}都不存在,则也可以省略“/”。

但是,此声明表示如果未预设路径和searchpart,则只能省略尾部斜杠。

在现实世界中,我之前能够在查询值之前省略一个尾部斜杠,但最近发现情况有所下降。如果您有一个查询,例如此http://my.domain.com?do=something,并且您在Internet Explorer中查看html页面,则链接由IE进行修复。如果您随后单击“文件”,“发送”,“通过电子邮件发送页面...”,则链接将添加到格式无效的电子邮件中。问题因查询值的内容而异,但我们能够创建无效的网址。

总之, 工作,但在边缘情况下会失败。

答案 4 :(得分:0)

可以在两者之间使用查询字符串也是下面的例子

/rest/mainfolder/subfolder?jsonFormat=stream&/value1/value2