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

Cha*_*had 60 url query-string

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

也就是说,我可以使用

http://example.com?querystring
Run Code Online (Sandbox Code Playgroud)

代替:

http://example.com/?querystring
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*ery 57

作为现代规范的问题,是的,允许跳过斜线,与此处所接受的答案相反.

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

让我们从最早到最晚依次考虑这些规范中的每一个:


RFC 1738:统一资源定位器(URL)(1994年发布)

隐需要由包括斜杠指定它可以被忽略,如果该URL既不包含路径,也没有查询字符串(称为searchpart,在这里).下面的结合是我的:

HTTP URL采用以下形式:

http://<host>:<port>/<path>?<searchpart>
Run Code Online (Sandbox Code Playgroud)

3.1节中描述的地方<host>和地点.如果: 省略,则端口默认为80.不允许使用用户名或密码. 是一个HTTP选择器,是一个查询字符串.这是和它的前面的"?" 是可选的.如果既不存在也不存在,也可以省略"/".<port><port><path><searchpart><path><searchpart><path><searchpart>


RFC 2396:统一资源标识符(URI):通用语法(1998年发布;"更新"RFC 1738)

省略斜线是可以接受的.这个RFC合法化了一些在方案之后没有双斜杠的奇怪的URL语法,但是如果我们忽略那些(它们是opaque_part规范的BNF中的那些)并且坚持包含主机的URL,那么我们发现这个absoluteURI定义是这样的......

absoluteURI   = scheme ":" ( hier_part | opaque_part )
Run Code Online (Sandbox Code Playgroud)

hier_part看起来像这样:

hier_part     = ( net_path | abs_path ) [ "?" query ]
Run Code Online (Sandbox Code Playgroud)

net_path看起来像这样:

net_path      = "//" authority [ abs_path ]
Run Code Online (Sandbox Code Playgroud)

其中a abs_path又被定义为以斜线开头.请注意,上面的语法中abs_path可选的 - 这意味着表单的URL scheme://authority?query是完全合法的.

这一变化的动机见附录G.2.RFC 1738和RFC 1808的修改:

问号"?" 从权限组件中userinfo的允许字符集中删除了字符,因为测试显示许多应用程序将其视为保留用于将查询组件与URI的其余部分分开.

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


RFC 3986:统一资源标识符(URI):通用语法(2005年发布;"废弃"RFC 2396)

同样,允许省略斜杠.该规范由话说,"路径"是必需的,它包含一个机构(主机)每一个URI,而且路径必须表示这要么以斜杠包括没有字符:

3.语法组件

通用URI语法由分层的组件序列组成,称为方案,权限,路径,查询和片段.

URI         = scheme ":" hier-part [ "?" query ] [ "#" fragment ]

hier-part   = "//" authority path-abempty
            / path-absolute
            / path-rootless
            / path-empty
Run Code Online (Sandbox Code Playgroud)

方案和路径组件是必需的,但路径可能为空(无字符).当存在权限时,路径必须为空或以斜杠("/")字符开头.

为了完整性,请注意path-abempty稍后定义:

path-abempty  = *( "/" segment )
Run Code Online (Sandbox Code Playgroud)

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


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

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

第4.3节告诉我们:

一个绝对URL字符串必须是下列之一

任意后跟"?" 和URL查询字符串.

由于HTTP和HTTPS是特殊方案,因此任何HTTP或HTTPS URL都必须满足这三个选项中的第一个 - 即,http:或者https:后跟scheme-relative-special-URL字符串,其中:

必须为" //",后跟有效的主机字符串,可选地后跟" :"和URL端口字符串,可选地后跟path-absolute-URL字符串.

路径绝对URL字符串被定义为开始以斜线,但在上述的绝对URL字符串的定义明确可选的; 因此,允许直接从主机到" ?"和查询字符串,因此URL http://example.com?query是合法的.


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

  • (可惜)浏览器(如Chrome),地址栏`?`前加斜杠:例如[https://stackoverflow.com?test](https://stackoverflow.com?test) 替换为[https://stackoverflow.com/?test](https://stackoverflow.com/?test) 加载页面时。我可以阻止这种行为吗? (2认同)

小智 48

不.跳过斜线是不正确的.可能适用于现代浏览器:但是,这并不能使其正确.

请参阅RFC1738 - URLRFC2396 - URI.

RFC1738的格式(我在这里排除了模式格式):

// <用户>:<密码> @ <主机>:<端口>/<URL路径>

它继续注意到:

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

在这种情况下,"?" 是url-path的一部分

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

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

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

  • -1; 这个答案几乎是完全错误的.它引用了20世纪90年代的规范,这些规范在编写这个答案时已经过时了,虽然它正确地将RFC 1738解释为需要斜杠,但它引用了RFC 2396而没有注意到RFC 2396明确允许斜杠被省略.请参阅[我的回答](http://stackoverflow.com/a/42193734/1709587),详细分析这些规范所说的内容,以及更多RFC 3986和WhatWG URL生活标准,这两者都允许斜杠被省略. (6认同)
  • 顺便说一句,人们,请*请*,***请***引用 IETF RFC 的 HTML 版本(例如 https://tools.ietf.org/html/rfc1738),而不是文本版本(例如http://www.ietf.org/rfc/rfc1738.txt)。除了更漂亮和更容易导航之外,它们还包含一个标题栏,可以清楚地标记规范是否已过时。我现在已经编辑了这个答案以引用 HTML 版本,但是如果这里的回答者首先阅读(并链接到)它们,那么任何人都不会花费 7 年的时间来注意到这个答案是引用自 2005 年以来已经过时的规范。 (4认同)

Chr*_*ter 5

在研究这个问题后,我发现了更多信息,添加到已接受的答案中:

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

权限组件以双斜杠“//”开头,并以下一个斜杠“/”、问号“?”或URI 结尾结尾。在权限组件中,字符“;”、“:”、“@”、“?”和“/”是保留的

基于此声明,问号应指示权限组件的结尾,带或不带斜杠。

http://tools.ietf.org/html/rfc1738(已替换标签)

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

但是,该语句表示只有在未预设路径和搜索部分时才可以省略尾随斜杠。

在现实世界中,我以前能够在查询值之前省略尾部斜杠,但最近发现了一种情况。如果您有类似http://my.domain.com?do=something的查询,并且您在 Internet Explorer 中查看 html 页面,则该链接已由 IE修复。如果您随后单击文件、发送、通过电子邮件寻呼...,则会将链接添加到格式无效的电子邮件中。问题因查询值的内容而异,但我们能够创建无效的 URL。

总之,它应该可以工作,但在边缘情况下会失败。