http://example.com/something/somewhere//somehow/script.js
双斜杠是否会破坏服务器端的任何内容?我有一个解析 URL 的脚本,我想知道如果我用一个斜杠替换多个斜杠,它是否会破坏任何东西(或更改路径)。特别是在服务器端,一些框架,如 CodeIgniter 和 Joomla 使用分段 url 方案和路由。我只想知道它是否会破坏任何东西。
http://example.com/something/somewhere//somehow/script.js
双斜杠是否会破坏服务器端的任何内容?我有一个解析 URL 的脚本,我想知道如果我用一个斜杠替换多个斜杠,它是否会破坏任何东西(或更改路径)。特别是在服务器端,一些框架,如 CodeIgniter 和 Joomla 使用分段 url 方案和路由。我只想知道它是否会破坏任何东西。
HTTP RFC 2396将路径分隔符定义为单斜杠。
但是,除非您使用某种 URL 重写(在这种情况下,重写规则可能会受到斜杠数量的影响),否则 uri 会映射到磁盘上的路径,但在(大多数?)现代操作系统(Linux/ Unix, Windows),一行中的多个路径分隔符没有任何特殊含义,所以 /path/to/foo 和 /path//to////foo 最终会映射到同一个文件。
可能会受到影响的另一件事是缓存。由于您的浏览器和服务器都会缓存单个页面(根据它们的缓存设置),通过稍微不同的 URI多次请求同一个文件可能会影响缓存(取决于服务器和客户端的实现)。
这个问题的正确答案是它取决于服务器的实现!
前言:根据定义 URL 路径语法的 RFC 2396,双斜杠在语法上是有效的。正如amn 所解释的,它因此意味着一个空的 URI 段。但是请注意,RFC 2396 只定义了语法,而不是路径的语义,包括空路径段,因此由您的服务器决定空路径的语义。
你没有提到你正在使用的服务器软件堆栈,也许你甚至在滚动你自己的?所以请用你的想象力来想象语义可能是什么!
实际上,我想指出一些与语义相关的日常原因,这意味着您应该避免使用双斜线,即使它们在语法上是有效的:
由于不是每个人都期望空有效,因此可能会导致错误。即使您今天的服务器技术可能与它兼容,您明天的服务器技术或您今天的服务器技术的下一个版本可能决定不再支持它。示例:当您尝试使用双斜杠指定路由模板时,ASP.NET MVC Web API 库会引发错误。
一些服务器可能将 // 解释为指示根路径。这可能是故意的,也可能是错误 - 然后很可能是安全错误,即目录遍历漏洞。
因为它有时是一个错误和一个安全错误,一些聪明的服务器堆栈和防火墙会看到子字符串'//',推断你可能正在尝试利用这样的错误,因此他们会返回403 Forbidden
or 400 Bad Request
etc,并拒绝实际对 URI 进行任何进一步的处理。
URL 不必映射到文件系统路径。因此,即使文件系统路径中的 // 等同于 /,您也不能保证所有 URL 都相同。
考虑“RFC3986:统一资源标识符(URI):通用语法”中相关path-absolute
非终结符的声明(如典型的那样,以ABNF语法指定):
path-absolute = "/" [ segment-nz *( "/" segment ) ]
然后考虑segment
在同一个文档中再往下几行的声明:
segment = *pchar
如果您可以阅读 ABNF,星号 ( *
) 指定以下元素pchar
可以重复多次以组成 a segment
,包括零次。学习这一点并重新阅读path-absolute
上面的声明,您可以看到一个可能为空segment
的imples,即第二个可能无限"/"
重复,因此允许有效的组合,如(至少一个的任意长度)作为(其本身用于指定规则)的一部分描述一个URI)。//////
/
path-absolute
由于所有 URL 都是 URI,我们可以得出结论,是的,根据引用的 RFC,URL 允许使用多个连续的正斜杠。
但并不是每个人都遵循或实现每个规范的 URI 解析器,所以我相当确定存在不兼容的 URI/URL 解析器和各种堆叠在这些之上的软件,这些极端情况会破坏更大的系统。
您可能要考虑的一件事是它可能会影响您在搜索引擎中的页面索引。根据这个网页,
同一路径重复 3 次的 URL 将不会在 Google 中编入索引
他们使用的例子是:
example.com/path/path/path/
如果您使用 ,我还没有确认这也是正确的example.com///
,但我当然想知道 SEO 优化是否对我的网站至关重要。
他们提到“这是因为 Google 认为它遇到了 URL 陷阱。” 如果其他人肯定知道答案,请对此答案添加评论;否则,我认为将这个案例包括在内以供考虑是相关的。
是的,它绝对可以破坏事物。
该规范认为http://host/pages/foo.html
和http://host/pages//foo.html
是不同的 URI,服务器可以自由地为它们分配不同的含义。/pages/foo.html
但是,大多数服务器会以相同的方式处理路径/pages//foo.html
(因为底层文件系统也是如此)。但是即使在处理这样的服务器时,额外的斜线也很容易破坏事情。考虑服务器返回相对 URI 的情况。
http://host/pages/foo.html + ../images/foo.png = http://host/images/foo.png
http://host/pages//foo.html + ../images/foo.png = http://host/pages/images/foo.png
让我解释一下这意味着什么。假设您的服务器返回一个包含以下内容的 HTML 文档:
<img src="../images/foo.png">
如果您的浏览器使用
http://host/pages/foo.html # Path has 2 segments: "pages" and "foo.html"
您的浏览器将尝试加载
http://host/images/foo.png # ok
但是,如果您的浏览器使用
http://host/pages//foo.html # Path has 3 segments: "pages", "" and "foo.html"
您可能会得到相同的页面(因为服务器可能无法区分/pages//foo.html
)/pages/foo.html
,但您的浏览器会错误地尝试加载
http://host/pages/images/foo.png # XXX
例如,在您的应用程序中为资源构建链接时,您可能会感到惊讶。
<script src="mysite.com/resources/jquery//../angular/script.js"></script>
不会解决, mysite.com/resources/angular/script.js
而是解决 mysite.com/resources/jquery/angular/script.js
您可能不想要的
双斜线是邪恶的,尽量避免它们。
你的问题是“它会破坏任何东西”。根据 URL 规范,允许使用额外的斜杠。不要阅读 RFC,这是一个快速实验,您可以尝试查看您的浏览器是否会默默地破坏 URL:
echo '<?= $_SERVER['REQUEST_URI'];' > tmp.php
php -S localhost:4000 tmp.php
我用 Safari 12.0 (14606.1.36.1.9) 和 Chrome 69.0.3497.100 测试了 macOS 10.14 (18A391),都得到了结果:
/你好世界
这表明使用额外的斜线对 Web 应用程序是可见的。
使用双斜杠时,某些用例会被破坏。这包括需要单斜杠 URL 的 URL 重定向/路由或其他直接分析 URI 的 CGI 应用程序。
但是对于提供静态内容的正常情况,例如您的示例,这仍然会获得正确的内容。但是对于使用不同斜杠访问的相同内容,客户端将获得缓存未命中。