Apache 的 Catch-all 重写规则不会导致 .htaccess 出现重复的 URL

Apache 的 Catch-all 重写规则不会导致 .htaccess 出现重复的 URL

您可以为 apache 制定一个捕获所有重写规则,其作用有点像别名,但可以在文件中实现,.htaccess而别名则不能。

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

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

您可以通过使根目录包含以下内容来将所有请求“别名”到测试文件夹.htaccess

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

第二个.htaccess包含:

RewriteEngine On

/file这很有效,通常就是您所需要的。但它有一个问题 - 它会创建多个有效的 URL。现在您可以使用和访问文件/test/file

通常这不是问题,但如果你添加一个名为的文件,/test/test你就会发现问题,因为假别名完全停止工作。如果子文件夹.htaccess本身很复杂,则会引起很大的麻烦。

有没有办法伪造一个别名,而.htaccess原始 URL 仍然不起作用?(有没有RewriteCond用于检查我们是否已被重写的子文件夹?)

答案1

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

是的,子目录中的第二个.htaccess文件可防止 URL 被重写(因为默认情况下 mod-rewrite 不会被继承)。您可以通过.htaccess在文档根目录中放置一个文件来重写所有尚未重写的请求来解决此问题。例如:

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

环境REDIRECT_STATUS变量在初始请求时为空,200在第一次重写成功后设置为(OK)。

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

  • 在子目录.htaccess文件中重复这些指令。(这样你就不需要RewriteCond在父.htaccess文件中使用上述指令了。)

  • 或者,启用 mod_rewrite 继承。但我认为您在 Apache 2.2 上会遇到困难。您可能需要类似RewriteOptions InheritBefore(在子目录.htaccess文件中)的内容,它仅在 Apache 2.4 上可用。

它只有一个问题——它创建了多个有效的 URL。

上述方法也解决了这个问题,因为现在所有请求都被重写(这更像是 ApacheAlias在服务器配置中的行为)。


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

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

THE_REQUEST占据第一线最初的请求标头,在重写请求时不会改变。

相关内容