似乎每隔几周我就要问更多.htaccess重写/重定向问题。每当我想到我理解它时,另一个扳手就会被投入到我的项目中,这表明我不会。
编辑:我原来的问题并不是很清楚,所以以下是为了更加简洁。
目前,所有.html文件都存在于根目录中。例如:http://example.com/about.html
除img,css等普通子目录外,没有任何子目录。
出于跟踪目的,如果有人在http://example.com/random/
中输入"随机"可以是任何字符串,我希望他们看到index.html
文件,而无需修改网址。目录"随机"根本不存在于服务器上。
about.html
等其他网页也是如此。如果有人输入http://example.com/random/about.html
,我希望他们看到about.html
页。
与此同时,我希望{em} http://example.com/random/about
或http://example.com/about
(缺少文件扩展名)也显示关于页面。
但是,如果有人输入的页面不存在,我希望它能使用ErrorDocument
示例:我没有名为" pickups.html"的文件。所以以下都是404s:
http://example.com/pickups.html
http://example.com/pickups
http://example.com/random/pickups.html
http://example.com/random/pickups
如果结束重定向/重写确实剥离了文件扩展名(因为它看起来更好)会很好。
我的想法是,任何以/
结尾的请求都只会提供站点根目录下的index.html文件。这样就留下了文件。
我的思维过程是:
我的初始代码(有帮助)是:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)/(.*)$ /$2 [R=301,L]
据我所知,在该代码中,我在最后一个斜杠后抓取所有内容并从文档根目录中提供它。不幸的是,它没有考虑到不存在的文件。
答案 0 :(得分:2)
从现有文件开始,它们将不加改变地传递。这也可以防止重写循环。
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
接下来是作为可选的虚拟子目录
的一部分请求的现有文件RewriteCond %{DOCUMENT_ROOT}/$2 -f
RewriteRule ^(.+/)?(.+)$ /$2 [L]
RewriteCond %{DOCUMENT_ROOT}/$2.html -f
RewriteRule ^(.+/)?(.+)$ /$2.html [L]
这会将请求拆分为可选前缀(.+/)?
和文件部分。如果此文件部分存在,可能附加了.html
,则表示您已完成。
接下来是带有斜杠的任何内容,只需重写为index.html
RewriteRule /$ /index.html [L]
其他任何内容都是对不存在的文件的请求,这会产生404
状态代码。
为了删除可选的.html
扩展名并删除现有文件的可选尾部斜杠/
,我们必须在开头插入两条规则
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{DOCUMENT_ROOT}/$2.html -f
RewriteRule ^(.+/)?(.+?)\.html/?$ /$1$2 [R,L]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{DOCUMENT_ROOT}/$2.html -f
RewriteRule ^(.+/)?(.+?)/$ /$1$2 [R,L]
这些规则与其他规则类似,只是它们执行重定向R|redirect
而不是重写,并且还有一个额外的条件来阻止重写循环。
将所有内容放在一起会产生
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{DOCUMENT_ROOT}/$2.html -f
RewriteRule ^(.+/)?(.+?)\.html/?$ /$1$2 [R,L]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{DOCUMENT_ROOT}/$2.html -f
RewriteRule ^(.+/)?(.+?)/$ /$1$2 [R,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteCond %{DOCUMENT_ROOT}/$2 -f
RewriteRule ^(.+/)?(.+)$ /$2 [L]
RewriteCond %{DOCUMENT_ROOT}/$2.html -f
RewriteRule ^(.+/)?(.+)$ /$2.html [L]
RewriteRule /$ /index.html [L]