确定在查询string之前跳过斜杠?
附加查询string时总是跳过尾部的斜线是否安全?
也就是说,我可以使用
http://example.com?querystring
代替:
http://example.com/?querystring
? 我用过的所有虚拟主机都支持这个function,但假设所有的服务器环境都支持这种方法是安全的吗? 这是标准吗?
不。跳过斜线是不正确的。 它可能适用于现代浏览器:但是,这并不正确。
请参阅RFC1738 – URL和RFC2396 – URI 。
每个RFC1738的格式(我已经排除了这里的模式格式):
// <用户>:<密码> @ <主机>:<端口> / <URLpath>
而且它还注意到:
主机(或端口)和urlpath之间的“/”不是urlpath的一部分。
在这种情况下,“?” 是其中的URLpath的一部分
取决于所使用的scheme,以及解释的方式。
还要注意,按照规范, 省略 “/ url-path”是完全有效的 – 注意在这种情况下明确包含了“/”。
因此,“foo.com?bar”是无效的,因为在url-path之前没有“/”。
就现代规范而言, 是的 ,可以跳过斜线,与这里所接受的答案相反。 尽pipe接受的答案正确地引用了RFC 1738(20多年前发布的!),但它错误地声称RFC 2396(1998年发布)要求使用斜杠,而忽略这两个规范反过来被RFC 3986废弃, 2005年(在接受答案之前还有好几年的时间)以及最近的WhatWG URL标准 ,两者都允许省略斜线。
从最早到最新,我们再来看看每个规格:
RFC 1738:统一资源定位符(URL) (1994年发布)
如果 URL不包含path和查询string (这里称为searchpart
) ,则隐含地要求包含斜线。 下面的Bolding是我的:
一个HTTP URL的格式如下:
http://<host>:<port>/<path>?<searchpart>
其中
<host>
和<port>
如3.1节所述。 如果省略:<port>
,则端口默认为80.不允许用户名或密码。<path>
是一个HTTPselect器,<searchpart>
是一个查询string。<path>
是可选的,<searchpart>
及其前面的“?”也是可选的。 如果<path>
和<searchpart>
都不存在,那么“/”也可以省略。
RFC 2396:统一资源标识符(URI):通用语法 (1998年发布;“更新”RFC 1738)
这里可以省略斜杠。 这个RFC合法化了一些在scheme之后没有双斜杠的奇怪的URL语法,但是如果我们忽略这些(在规范的BNF中是那些带有opaque_part
的)并且坚持包含主机的URL,那么我们发现absoluteURI
是这样定义的…
absoluteURI = scheme ":" ( hier_part | opaque_part )
而且一个hier_part
看起来像这样:
hier_part = ( net_path | abs_path ) [ "?" query ]
net_path
如下所示:
net_path = "//" authority [ abs_path ]
其中abs_path
依次定义为以斜杠开始。 请注意, abs_path
在上面的语法中是可选的 – 这意味着格式scheme://authority?query
的URL是完全合法的。
附录G.2暗示了这种变化的动机。 RFC 1738和RFC 1808的修改 :
问号“?” 字符已从权限组件中userinfo的允许字符集中移除,因为testing显示许多应用程序将其视为保留用于将查询组件与URI的其余部分分开。
换句话说,现实世界中的代码假设URL中的第一个问号标记了查询string的开始,因此规范被实际更新以符合实际。
RFC 3986:统一资源标识符(URI):通用语法 (2005年发布;“废止”RFC 2396)
再次,可以省略斜线。 这个规范expression了这一点,它说每个包含一个权限(主机)的URI都需要一个“path”,该path必须以斜杠开头或者不包含任何字符:
3.语法组件
通用URI语法由称为scheme,权威,path,查询和片段的组件的分层序列组成。
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] hier-part = "//" authority path-abempty / path-absolute / path-rootless / path-empty
path和path组件是必需的,尽pipepath可能是空的(没有字符)。 当授权存在时,path必须为空或以斜杠(“/”)字符开头。
为了完整性,请注意,后面的path-abempty
是由以下定义的:
path-abempty = *( "/" segment )
这确实允许它不包含字符。
由WhatWG 标准的url(在主动维护下的生活标准,2012年首次创build,目标是废除RFC 3986)
再次,省略斜线是可以接受的,虽然这次我们没有BNF看,而是需要阅读大量的散文。
4.3节告诉我们:
绝对URLstring必须是以下之一
- 一个URL-schemestring ,它是一个特殊scheme的ASCII不区分大小写的匹配,而不是ASCII的不区分大小写的“
file
”匹配,后跟“:
”和一个scheme-relative-special-URLstring- 一个URLschemestring ,它不是一个特殊scheme的ASCII不区分大小写的匹配,后跟“:”和一个相对URLstring
- 一个URL模式string ,它是“file”的ASCII不区分大小写的匹配,后跟“:”和一个scheme-relative-file-URLstring
任何可选的后面跟“?” 和一个URL查询string。
由于HTTP和HTTPS是特殊的scheme ,任何HTTP或HTTPS URL必须满足这三个选项中的第一个 – 即http:
或https:
后跟一个scheme-relative-special-URLstring ,其中:
必须是“
//
”,然后是一个有效的主机string ,可选地后跟“:
”和一个URL端口string ,可选地后跟一个path绝对URLstring 。
path绝对URLstring被定义为以斜杠开始,但在上面的绝对URLstring的定义中是明确可选的; 因此,允许从主机直接转到“ ?
”和查询string,因此http://example.com?query
这样的URL是合法的。
当然,这些都不能保证每个Web服务器或HTTP库都能接受这样的URL,也不会将它们视为在语义上等同于包含斜线的URL。 但就规格而言,跳过斜线是完全合法的。
假设这是不安全的。 Web服务器和自包含的Web应用程序通常会检查请求中提供的URL,但不能保证他们将/abc
等同于/abc/
。 Web服务器和自包含的Web应用程序可以根据从URL中收集的信息做任何他们喜欢的事情 ,而不一定是您所期望的。 您将不得不找出有关特定URL的约定。
请注意,当然,大多数Web服务器和Web应用程序框架都尽力接受各种input并适当地处理它们。 因此,在大多数情况下,Web服务器或自包含的Web应用程序将把/abc
等同于/abc/
。 但请记住,因为服务器可以做任何喜欢的path,这只是一个普遍的观察,可能有许多例外。
在研究这个问题后,我发现了一些更多的信息,
http://tools.ietf.org/html/rfc2396
权限组件前面是一个双斜杠“//”,由下一个斜杠“/”,问号“?”或URI的末尾来终止。 在权限组件中,字符“;”,“:”,“@”,“?”和“/”被保留
基于这个陈述,问号应该表明权威组件的结束,不论是否有斜线。
http://tools.ietf.org/html/rfc1738 (标签取代)
{path}是可选的,{searchpart}及其前面的“?”是可选的。 如果{path}和{searchpart}都不存在,那么“/”也可以省略。
但是,此声明表示,如果path和search部分都未预设,则只能省略尾部斜线。
在现实世界中,我以前能够在查询值之前省略斜线,但是最近发现情况下降了。 如果你有一个像http://my.domain.com?do=something这样的查询,并且你在Internet Explorer中查看一个html页面,那么这个链接就被IE所固定 。 如果您点击“文件”,“发送”,“通过电子邮件发送页面…”,该链接将以无效的格式添加到电子邮件中。 这些问题因查询值的内容而异,但我们能够创build无效的URL。
总之,它应该工作,但在边缘情况下跌倒。