且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

通过隐藏的.php和.htm(L)扩展和重定向到无扩展名的URL强制的URL重写

更新时间:2022-11-27 09:24:28

有逻辑缺陷的前两个规则,因为它是一个存在的PHP或HTML文件。该URI检查也是生效的重写规则模式的复制和!˚F暗示!-d。您还可以折叠这些成一个单一的规则:

There's a logic flaw in the first two rules in that it's the php or html file that exists. The URI check is also in effect a duplicate of the rewrite rule pattern and !f implies !-d. You can also fold these into a single rule:

RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*?)\.(php|html?)$        $1   [R=301,NC]

最后两个都OK,但我调换顺序,如果HTML请求是比较常见的比PHP

The last two are OK, but I'd swap the order if html requests are more common than php

选项+多视图实现了被称为的内容协商,并在这样的Apache调用一个子查询来解析文件名的根名称。其中之一是它做的事情是扫描目录已知filename.extension组合,所以在这种情况下,如果 xxx.php 存在,你的要求是 XXX 那么它将替代的 xxx.php ,然后做了一个内部​​重定向,然后使你的第一个规则火,取出的.php 扩展这会导致你看到的错误。

Options +MultiViews implements a concept known as content negotiation, and in doing this Apache invokes a subquery to parse the filename root name. One of the things that it does is to scan the directory for known filename.extension combinations so in this case if xxx.php exists and your request is for xxx then it will substitute xxx.php and do an internal redirection, which then causes your first rule to fire, removing the .php extension and this causes the error that you see.

所以(我),你需要禁用多视图,以及(ii)同上子查询; (三)检测和prevent重试循环。这是一种解决方案,这将做你想要的:

So (i) you need to disable multiviews, and (ii) ditto subqueries; (iii) detect and prevent retry loops. This is one solution which will do what you want:

Options +FollowSymLinks  -MultiViews
RewriteEngine on
RewriteBase /foo

RewriteCond %{ENV:REDIRECT_END}  =1
RewriteRule ^ - [L,NS]

RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*?)\.(php|html?)$        $1   [R=301,NC,NS]

RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule (.*)$ $1.html   [L,E=END:1,NS]

RewriteCond %{REQUEST_FILENAME}\.htm -f
RewriteRule (.*)$ $1.htm    [L,E=END:1,NS]

RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule (.*)$ $1.php    [L,E=END:1,NS]