.htaccess重写以强制在末尾添加斜杠

39

我在我的htaccess文件中有以下代码:

# Force Trailing Slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^[^/]+$ %{REQUEST_URI}/ [L,R=301]

当我访问www.mydomain.com/test时,似乎一切正常,它将其重定向到/test/。 但问题是当我访问 www.mydomain.com/test/another 时,它不会在 "another" 后面添加尾随斜杠。

有谁知道如何修改我的代码,使尾随斜杠在 URL 长度不同的情况下都能工作吗?

谢谢!

10个回答

72

一个稍微更健壮一些的答案,基于上面的答案

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

RewriteCond将检查是否存在该名称的文件,如果不存在,则执行RewriteRule。这比手动列出扩展名更具未来性!


我尝试过这个,但它会在以 .html 结尾的文件后面添加一个斜杠。 - moobot
如果URL导向一个真实的文件,它不应该触发这个规则;你是否在你的“美化”的URL中不必要地添加了“.html”? - jeffbyrnes
1
不是我,但我猜是Magento!谢谢回复,不过我找到了一个重定向,它只会将其添加到没有扩展名的URL中: http://www.paulund.co.uk/using-htaccess-to-force-trailing-slash - moobot
1
这个答案对我也非常有用。唯一遇到的问题是我的重定向指向了一个奇怪的服务器路径。我通过添加RewriteBase /来解决这个问题。这使得重定向起作用非常顺畅! - Martie
1
这对我完美地起作用了。谢谢! 当尝试此或任何解决方案时,请记得清除您的浏览器缓存。 - Tomas Gonzalez
显示剩余2条评论

36
RewriteRule ^(.*)([^/])$ http://%{HTTP_HOST}/$1$2/ [L,R=301]

编辑: 如果你想要排除某些请求,比如针对 php 文件的请求:

RewriteCond %{REQUEST_URI}  !\.(php|html?|jpg|gif)$
RewriteRule ^(.*)([^/])$ http://%{HTTP_HOST}/$1$2/ [L,R=301]

1
您可能还想包含CSS和JS。这非常有用! - Eruant
@undone 我能问一下,html?后面的 ?代表什么意思,为什么你没有在php?中加上问号? - Daniel W.
10
正则表达式中的问号表示前一个字符(在这种情况下是 l)在字符串中可能存在也可能不存在。因此,它可以覆盖 htmhtml 扩展名! - undone

7

虽然Death's solution可以解决问题,但是当你忘记将某些文件类型添加到列表中时,它可能会很烦人。你可以使用条件中的!-f来强制所有不直接指向文件的URL添加尾随斜杠。

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/])$ http://%{HTTP_HOST}/$1/ [L,R=301]

我尝试过这个,但它会在以 .html 结尾的文件后面添加一个斜杠。 - moobot
我也尝试过这个方法,但仍然看到像sitemap.xml这样的页面添加了尾随斜杠。服务器设置是否决定了哪些文件被视为要下载的文件和要在浏览器中呈现的文件,并且这会影响对!-f的解释吗? - Mattypants

3

对我来说,接受的答案没有起作用。这个来自SEOMoz的解决方案起了作用:

# Ensure all URLs have a trailing slash.
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://www.example.com/$1/ [L,R=301]

注意每个规则中的 RewriteBase /。至少,在我删除它时,它就不能工作了。


1
这对我非常有效。(来自用户Ajax的评论)
其他链接的问题是在应用重定向规则后我的CSS停止工作,但是使用下面的重写规则CSS也可以正常工作。
RewriteRule ^((.*)[^/])$ $1/ [L,R=301]

完整的代码

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_URI} !(.*)/$
    #Force Trailing slash
    RewriteRule ^((.*)[^/])$ $1/ [L,R=301]
</IfModule> 

0
RewriteRule ^(.*)[^/]$ $1/ [L,R=301]

这应该很好用。它只是检查结尾字符是否不是斜杠并添加一个。


这个解决方案也会给文件添加一个斜杠! - Phil

0

这对我来说完全有效,不像一些人建议的“-f”标志那样依赖于实际文件的评估:

RewriteCond %{REQUEST_URI} !\.[a-z0-9]+$ [NC]
RewriteRule ^(.*)([^/])$ http://%{HTTP_HOST}/$1$2/ [L,R=301]

0
以上示例由于规则末尾强制添加斜杠,例如$1$2/对我无效。
对于我来说,这个例子有效(我在WordPress中使用它并重定向到HTTPS)。您必须在RewriteEngine和RewriteBase行后面添加条件和规则行:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

# I added these two lines for redirect to HTTPS
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://www.yoursite.com/$1 [R=301,L]

RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress`

0

为了强制使用尾部斜线,您可以使用:

RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule [^/]$ %{REQUEST_URI}/ [L,R]

注意:在 mod-rewrite 自动添加尾随斜杠之前运行的 mod-dir 模块会自动为请求一个存在目录时添加尾随斜杠,因此我们必须从规则中排除目录,否则在某些服务器上使用不带 RewriteCond %{REQUEST_FILENAME} !-d 的规则,您将最终到达 /dir// 或者如果您已关闭 directorySlash,则可能会导致问题。

以上规则会为所有请求(包括扩展名文件)添加尾随斜杠,如果您不希望文件有尾随斜杠,可以通过添加以下条件来将它们排除在规则之外。

RewriteCond %{REQUEST_FILENAME} !-f

-3
<rule name="Remove trailing slash" stopProcessing="true">
    <match url="^([^.]+)/$" />

在您的配置文件中添加此规则,这对我有效。


<rule name="Remove trailing slash" stopProcessing="true"> <match url="^([^.]+)/$" /> - manikandan krishnamoorthy
你应该将代码行添加到你的答案中,而不是将其作为注释! - Timothy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接