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多次请求同一文件可能会影响缓存(取决于服务器和客户端实现)。
path_segments
至少由一个segment
令牌组成,而segment
本身可以是空长度。这意味着像//
这样的字符序列在URI中是完全有效的。 - Armen Michaelihttp://host/a/b/c/d + ../../e = http://host/a/e
,而http://host/a/b/c//d + ../../e = http://host/a/b/e
。" - ikegami这个问题的正确答案是它取决于服务器的实现!
前言:根据定义URL路径语法的RFC 2396,双斜杠在语法上是有效的。正如amn所解释的那样,它因此意味着一个空的URI段。但请注意,RFC 2396仅定义了路径的语法,包括空路径段的语义,因此由您的服务器决定空路径的语义。
您没有提到您正在使用的服务器软件堆栈,也许您甚至正在自己开发?因此,请想象一下语义可能是什么!
实际上,我想指出一些日常语义相关的原因,即使它们在语法上是有效的,您也应该避免使用双斜杠:
当不是每个人都认为空值应该是有效的时,它可能会导致错误!即使您今天的服务器技术与之兼容,但您明天的服务器技术或今天的服务器技术的下一个版本可能不兼容。(例如:ASP.NET MVC Web API库在尝试指定具有双斜杠的路由模板时会抛出错误。)
一些服务器可能会将//
解释为表示根目录。这可能会成为目录遍历漏洞 - 然后通常是安全漏洞(查找“目录遍历漏洞”)。
因为它有时是一个错误和安全漏洞,所以防御性设计的服务器堆栈和防火墙将假定任何传入请求中的子字符串'//'都是可能的尝试利用漏洞,因此他们将通过返回403 Forbidden
、404 Not Found
或400 Bad Request
来阻止它 - 而不会实际进一步处理URI或请求。
URL与文件系统路径不必一一对应。因此,即使在文件系统路径中//等同于/,也不能保证所有URL都是如此。
考虑在“RFC3986:统一资源标识符(URI):通用语法”中声明相关的path-absolute
非终端符号(通常使用ABNF语法进行指定):
path-absolute = "/" [ segment-nz *( "/" segment ) ]
segment
声明:segment = *pchar
*
)表示以下元素pchar
可以重复多次以组成一个segment
,包括零次。通过学习这一点并重新阅读上面的path-absolute
声明,您可以看到一个可能为空的segment
意味着第二个"/"
可能会无限重复,因此允许像//////
(至少一个/
的任意长度)这样的有效组合作为path-absolute
的一部分(它本身用于指定描述URI的规则)。http://host/a////b
是一个有效的URI,但这不是OP所问的。事实上,您引用的RFC本身就说它们不等同。事实上,即使http://host/a////b
是有效的,也不能认为它等同于http://host/a/b
。 - ikegamihttp://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
<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
你可能需要考虑的一件事是,这可能会影响到搜索引擎对你页面的索引。根据this网页所述:
重复3次相同路径的URL将不会被Google索引
他们使用的例子是:
example.com/path/path/path/
example.com///
是否也是如此,但如果SEO优化对我的网站至关重要,我肯定想找出答案。例如,在为应用程序中的资源构建链接时,您可能会感到惊讶。
<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
我测试了macOS 10.14(18A391)和Safari 12.0(14606.1.36.1.9)以及Chrome 69.0.3497.100,两者都得到了以下结果:
/hello//world
这表明使用额外的斜杠对Web应用程序是可见的。
在使用双斜杠时,某些用例将会出现问题。这包括期望单斜杠URL或直接分析URI的其他CGI应用程序的URL重定向/路由。
但对于提供静态内容的正常情况,例如您的示例,这仍将获得正确的内容。但客户端将针对使用不同斜杠访问的相同内容获得缓存未命中。
..
的双斜杠的特殊情况。 - William Entrikenhttp://url/a//b
中引用../xyz
以获取http://url/a/xyz
不是预期行为? - William Entrikens | / + | / | g
)的URL不同。很可能您的服务器将提供相同的文件。您需要对相对URL的影响负责。 - William Entriken