Force trailing slash
I'm trying to force a trailing slash to my URLs, but I can't make it work the way I want. This is my .htaccess file:
RewriteEngine on
#Force trailing slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !index.php
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ /$1/ [L,R=301]
#Subdomains
RewriteCond %{HTTP_HOST} !^开发者_开发问答www\.example\.com [NC]
RewriteCond %{HTTP_HOST} ^([^/.]+)\.example\.com$
RewriteCond $1/%1 !^([^/]+)/\1$
RewriteRule ^/([^/]+)? /%1%{REQUEST_URI} [L]
#Point everything to page.php
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteCond $1 !^(.*).(php|css|js|png|jpg|gif|htm|html)$
RewriteRule ^(.*)$ page.php?q=$1 [L,NC]
If I go to "en.example.com/about" I'm redirected to "en.example.com/en/about/", which is an invalid page.
How can I make this work?
The problem here is that the L flag causes a restart of the rewriting process with the rewritten URL (I’ve already told you that, didn’t I?):
Remember, however, that if the
RewriteRule
generates an internal redirect (which frequently occurs when rewriting in a per-directory context), this will reinject the request and will cause processing to be repeated starting from the firstRewriteRule
.
Now when /about
is requested, the first rule get’s applied and redirects to /about/
. The subsequent request of /about/
is then processed, at first the third rule is applied and the URL path is rewritten to /page.php
. So far, so good.
But now the internal redirect takes place and the rewriting process is restarted with the new URL path /page.php
. This is then fetched by the first rule again and redirected externally to /page.php/
.
The second rule shouldn’t be applied at all as the pattern ^/
should never match as the per-directory path prefix is removed before testing the pattern when using mod_rewrite in an .htaccess file:
When using the rewrite engine in .htaccess files the per-directory prefix (which always is the same for a specific directory) is automatically removed for the pattern matching and automatically added after the substitution has been done.
But these rules should work:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .*[^/]$ /$0/ [L,R=301]
RewriteCond %{HTTP_HOST} ^([^/.]+)\.example\.com$ [NC]
RewriteCond %1 !=www [NC]
RewriteCond $0/%1 !^([^/]+)/\1$
RewriteRule ^[^/]* /%1%{REQUEST_URI} [L]
RewriteCond %{HTTP_HOST} !=www.example.com [NC]
RewriteCond $1 !.*\.(php|css|js|png|jpg|gif|htm|html)$
RewriteRule .* page.php?q=$0 [L]
精彩评论