提问人:Joseph 提问时间:4/15/2012 更新时间:3/21/2023 访问量:46991
带有多个正斜杠的 URL,它会破坏任何东西吗?
url with multiple forward slashes, does it break anything?
问:
http://example.com/something/somewhere//somehow/script.js
双斜杠会破坏服务器端的任何东西吗?我有一个解析 URL 的脚本,我想知道如果我用一个斜杠替换多个斜杠,它是否会破坏任何东西(或更改路径)。特别是在服务器端,一些框架,如 CodeIgniter 和 Joomla,使用分段 url 方案和路由。我只想知道它是否破坏了任何东西。
答:
URL 不必映射到文件系统路径。因此,即使文件系统路径中的 // 等同于 /,您也不能保证所有 URL 都如此。
HTTP RFC 2396 将路径分隔符定义为单斜杠。
但是,除非您使用某种 URL 重写(在这种情况下,重写规则可能会受到斜杠数量的影响),否则 uri 映射到磁盘上的路径,但在(大多数?)现代操作系统(Linux/Unix、Windows)中,一行中的多个路径分隔符没有任何特殊含义,因此 /path/to/foo 和 /path//to///foo 最终会映射到同一个文件。
另一个可能受到影响的事情是缓存。由于浏览器和服务器都缓存单个页面(根据其缓存设置),因此通过略有不同的 URI 多次请求同一文件可能会影响缓存(具体取决于服务器和客户端实现)。
评论
path_segments
segment
//
http://host/a/b/c/d + ../../e = http://host/a/e
http://host/a/b/c//d + ../../e = http://host/a/b/e
考虑“RFC3986:统一资源标识符 (URI):通用语法”中相关非终端的声明(在 ABNF 语法中指定,这是典型的):path-absolute
path-absolute = "/" [ segment-nz *( "/" segment ) ]
然后考虑同一文档中再往下几行的声明:segment
segment = *pchar
如果可以读取 ABNF,则星号 () 指定以下元素可以重复多次以组成 ,包括零次。了解这一点并重新阅读上面的声明,您可以看到,一个潜在的空意味着第二个可以无限重复,因此允许有效的组合,例如(至少一个的任意长度)作为(它本身用于指定描述 URI 的规则)的一部分。*
pchar
segment
path-absolute
segment
"/"
//////
/
path-absolute
由于所有 URL 都是 URI,我们可以得出结论,是的,根据引用的 RFC,URL 允许多个连续的正斜杠。
但并不是每个人都遵循或实现每个规范的 URI 解析器,所以我相当确定存在不合规的 URI/URL 解析器以及各种软件,这些软件堆叠在这些软件之上,这些极端情况会破坏更大的系统。
评论
http://host/a////b
http://host/a////b
http://host/a/b
您可能需要考虑的一件事是,它可能会影响您在搜索引擎中的页面索引。根据这个网页,
相同路径重复 3 次的网址不会在 Google 中编入索引
他们使用的例子是:
example.com/path/path/path/
如果您使用,我还没有确认这也是正确的,但我当然想知道 SEO 优化是否对我的网站至关重要。example.com///
他们提到“这是因为谷歌认为它已经进入了URL陷阱。如果其他人肯定知道答案,请在此答案中添加评论;否则,我认为将本案列入审议范围是相关的。
这个问题的正确答案是它取决于服务器的实现!
前言:根据 RFC 2396,双斜杠在语法上是有效的,它定义了 URL 路径语法。正如 amn 所解释的,因此它意味着一个空的 URI 段。但请注意,RFC 2396 仅定义语法,而不是路径的语义,包括空路径段,因此由服务器决定空路径的语义。
你没有提到你正在使用的服务器软件堆栈,也许你甚至在滚动你自己的?因此,请发挥您的想象力,了解语义可能是什么!
实际上,我想指出一些日常语义相关的原因,这意味着即使它们在语法上是有效的,你也应该避免使用双斜杠:
当不是每个人都认为空应该是有效的时,它可能会导致错误!即使你今天的服务器技术可能与它兼容,你明天的服务器技术或今天的下一个版本的服务器技术可能不兼容。(示例:当您尝试使用双斜杠指定路由模板时,ASP.NET MVC Web API 库会引发错误。
某些服务器可能会解释为指示根。这可能成为目录遍历错误 - 然后通常是一个安全错误(查找“目录遍历漏洞”)。
//
因为它有时是一个错误,也是一个安全错误,防御性设计的服务器堆栈和防火墙将假设子字符串“//”,在任何传入请求中都可能试图利用错误,因此他们将通过返回 、 或 - 来阻止它,而无需实际进一步处理 URI 或请求。
403 Forbidden
404 Not Found
400 Bad Request
你的问题是“它会破坏任何东西吗”。在 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 应用程序。
但对于提供静态内容的正常情况,例如您的示例,这仍将获得正确的内容。但是,对于使用不同斜杠访问的相同内容,客户端将出现缓存未命中。
评论
..
../xyz
http://url/a//b
http://url/a/xyz
例如,在为应用中的资源构建链接时,您可能会感到惊讶。
<script src="mysite.com/resources/jquery//../angular/script.js"></script>
不会解决,而是解决你可能不想要的mysite.com/resources/angular/script.js
mysite.com/resources/jquery/angular/script.js
双斜线是邪恶的,尽量避免它们。
是的,它绝对会破坏东西。
该规范将 和 视为不同的 URI,服务器可以自由地为它们分配不同的含义。但是,大多数服务器将以相同的方式处理路径(因为底层文件系统也是如此)。但即使在处理此类服务器时,额外的斜杠也很容易破坏事物。请考虑服务器返回相对 URI 的情况。http://host/pages/foo.html
http://host/pages//foo.html
/pages/foo.html
/pages//foo.html
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
评论