捕捉所有重写规则为Apache不会导致.htaccess重复的URL

您可以为apache制定一个全面的重写规则,它的行为有点像一个别名,但可以在.htaccess文件中实现,而别名不能。

举个例子,假设你的文档根是这样的层次结构:

 /.htaccess /test/ /test/.htaccess /test/file 

您可以通过使根.htaccess包含以下命令来“testing”到testing文件夹的所有请求:

 RewriteEngine On RewriteRule ^(.*)$ /test/$1 [L] 

而第二个.htaccess包含:

 RewriteEngine On 

这很好,通常是你所需要的。 它只是有一个问题 – 它创build了多个有效的url。 现在你可以用/file/test/file来访问这个/test/file

通常这不是问题,但如果添加一个名为/test/test的文件,将会看到问题,因为假别名完全停止工作。 如果子文件夹有一个复杂的.htaccess它自己可能会导致重大的麻烦。

有没有办法假冒一个.htaccess别名没有原来的url仍然工作? (任何RewriteCond的子文件夹,将检查,如果我们已经被重写或不?

…但如果你添加一个名为/test/test的文件,你将会看到这个问题,因为假别名完全停止工作。

是的,子目录中的第二个.htaccess文件可以防止URL被重写(因为mod-rewrite默认是不会被inheritance的)。 只要在文档根目录中有一个.htaccess文件来重写所有尚未被重写的请求,就可以解决这个问题。 例如:

 RewriteEngine On RewriteCond %{ENV:REDIRECT_STATUS} ^$ RewriteRule (.*) /test/$1 [L] 

初始请求中的REDIRECT_STATUS环境variables为空,并在第一次成功重写后设置为200 (OK)。

但是,如果您仍然需要子目录中的.htaccess文件(对于其他mod_rewrite指令),那么您需要:

  • 在子目录.htaccess文件中重复这些指令。 (然后你不会严格地需要父级.htaccess文件中的上述RewriteCond指令。)

  • 或者,启用mod_rewriteinheritance。 但是我认为你会在Apache 2.2上挣扎。 你可能需要像RewriteOptions InheritBefore (在子目录.htaccess文件中),它只在Apache 2.4上可用。

它只是有一个问题 – 它创build了多个有效的url。

上面的方法也解决了这个问题,因为现在所有的请求都被重写了(这更像是Apache Alias在服务器configuration中的performance)。


否则,如果直接访问基本子目录,则需要确保基本子目录是唯一的,以便能够实现规范redirect回到文档根目录。 例如:

 RewriteCond %{THE_REQUEST} ^[AZ]{3,9}\ /unique-subdir RewriteRule (.*) /$1 [R=301,L] 

THE_REQUEST保存了初始请求头的第一行,并且在请求被重写时不会改变。