强制尾随斜杠。处理开销?

时间:2017-05-17 16:10:29

标签: apache .htaccess mod-rewrite trailing-slash

我想强制文件夹中的尾部斜杠而不是文件中的尾部斜杠。我想要一种方法来避免可能的重复。

我找到了答案: Htaccess: add/remove trailing slash from URL

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/])$ /$1/ [L,R] # <- for test, for prod use [L,R=301]

我尝试了我的.htaccess,似乎效果很好

但我在Apache文档中发现类似的代码可能导致处理开销&#34;

http://httpd.apache.org/docs/2.0/misc/rewriteguide.html

我不知道我是否理解这一异议。这也适用于该代码吗?将它放在.htaccess中以便在必要时强制使用正确的尾部斜线是一种好习惯吗?如果不是最好的方法是什么?

1 个答案:

答案 0 :(得分:2)

  

我尝试了.htaccess,效果很好

你确定吗? (也许它适用于您的特定情况??)但是您不应该将这两个规则块一起使用,它们则相反。第一个删除尾部斜杠(对于非目录),第二个规则附加一个尾部斜杠(对于非文件)。

例如,如果您发出/foo/请求,其中/foo既不映射到目录也不映射文件,那么您将获得重定向循环。删除尾部斜杠,然后附加等等。

  

强制文件夹中的尾部斜杠而不是文件中的尾部斜杠

嗯,实际上,这些规则都没有“强制在文件夹中尾随斜杠”。如果你有DirectorySlash On(默认值),那么mod_dir强制在目录上使用尾部斜杠(使用301重定向)。

  

可能导致“处理开销”

处理开销是检查每个请求(与RewriteRule 模式匹配)上是否存在目录和/或文件。是的,这是一个开销 - 但是,它被认为是边际的,因为开销会增加。大多数CMS使用与前端控制器类似的技术,例如:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]

但是,这可以进行优化。您可以在文件的开头包含一个异常“静态资源(图像,CSS,JS等)”,并阻止目录/文件检查这些请求。例如:

RewriteRule .\.(jpe?g|png|gif|css|js)$ - [L]

这只会检查以这些文件扩展名结尾的任何请求并停止进一步处理,因此不会对这些请求执行目录/文件检查。

RewriteRule ^(.*[^/])$ /$1/ [L,R] # <- for test, for prod use [L,R=301]

除了:(以防万一这是在您的实际代码中。)Apache实际上不支持行结束注释。在这种情况下它会“起作用”,但未来的编辑可能会破坏可怕,所以最好避免。请参阅我对其他问题的回答:https://stackoverflow.com/a/31770372/369434

  

我想在文件夹中强制使用尾部斜杠,而不是在文件中强制使用斜杠。

更新:我假设我们只处理物理文件和目录,没有虚拟 URL与前端控制器等路由。

在这种情况下,您不必对强制目录上的尾部斜杠执行任何操作(如上所述)。提供DirectorySlash Off而不是设置,那么你应该已经很好了。这使得mod_dir在请求没有尾部斜杠的目录时自动附加尾部斜杠(通过301重定向)。 (你发布的第二条规则也是一样的,但是如果mod_dir正在做它的事情,这是多余的。)

要从文件中删除尾部斜杠,您只需要发布的两个规则中的第一个规则:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [R,L]

如果请求中存在尾随斜杠,则它将删除尾随斜杠,而不是对物理目录的请求。很难进一步优化这一点。只有在开头有一个尾部斜杠时才会处理该规则 - 因此捕获的请求数应该是最小的。但是,您必须链接到应用程序中的规范(非尾部斜杠)URL。

上面提到的排除静态资源的优化是可选的。如果您的.htaccess文件中没有其他mod_rewrite指令,那么它几乎没有任何好处。