apache / 2.4 / reference / rewrite-avoid.html

何时不使用 mod_rewrite

本文档是对mod_rewrite reference documentation的补充。它描述了有关mod_rewrite的最重要概念之一-即何时避免使用它。

如果发现其他替代方法,mod_rewrite应该被视为万不得已。当有更简单的选择时使用它会导致配置混乱,易碎且难以维护。理解还有哪些其他替代方法对于掌握mod_rewrite非常重要。

请注意,这些示例中的许多示例在您的特定服务器配置中都不会起作用,因此,理解它们,而不只是将示例剪切并粘贴到您的配置中,这一点很重要。

mod_rewrite是正确工具的最常见情况是,最好的解决方案需要访问服务器配置文件,而您没有访问权限。某些配置指令仅在服务器配置文件中可用。因此,如果您处在只能使用.htaccess 文件的托管环境中,则可能需要求助于mod_rewrite

Simple Redirection

mod_alias提供了RedirectRedirectMatch指令,它们提供了一种将一个 URL 重定向到另一个 URL 的方法。应该使用这些指令而不是RewriteRule来实现将一个 URL 或一类 URL 进行这种简单的重定向到其他地方的操作。 RedirectMatch允许您在重定向条件中包括正则表达式,从而提供使用RewriteRule的许多好处。

RewriteRule的常见用法是重定向整个 URL 类。例如,必须将/one目录中的所有 URL 都重定向到http://one.example.com/,或者可能将所有http请求都重定向到https

Redirect指令可以更好地处理这些情况。请记住,Redirect保留路径信息。也就是说,URL /one的重定向还将重定向该 URL 下的所有 URL,例如/one/two.html/one/three/four.html

要将/one下的 URL 重定向到http://one.example.com,请执行以下操作:

Redirect "/one/" "http://one.example.com/"

要将一个主机名重定向到另一个主机名,例如example.comwww.example.com,请参见Canonical Hostnames配方。

要将http个 URL 重定向到https,请执行以下操作:

<VirtualHost *:80>
    ServerName www.example.com
    Redirect "/" "https://www.example.com/"
</VirtualHost>

<VirtualHost *:443>
    ServerName www.example.com
    # ... SSL configuration goes here
</VirtualHost>

如果在同一作用域中还有其他RewriteRule指令,则使用RewriteRule执行此任务可能是合适的。这是因为,当在同一作用域中有RedirectRewriteRule指令时,无论配置文件在外观中的 Sequences 如何,RewriteRule指令都将首先运行。

对于* http 到 https *重定向,如果您无权访问主服务器配置文件,而必须在.htaccess文件中执行此任务,则使用RewriteRule是合适的。

URL Aliasing

Alias伪指令提供从 URI 到目录的 Map-通常是DocumentRoot之外的目录。尽管可以使用mod_rewrite进行此 Map,但是出于简单和性能的考虑,Alias是首选方法。

Using Alias

Alias "/cats" "/var/www/virtualhosts/felines/htdocs"

当您无权访问服务器配置文件时,使用mod_rewrite执行此 Map 可能是合适的。别名只能在服务器或虚拟主机上下文中使用,而不能在.htaccess文件中使用。

如果在服务器上启用了Options FollowSymLinks,则符号链接将是完成同一任务的另一种方法。

Virtual Hosting

尽管可以处理使用 mod_rewrite 的虚拟主机,但这很少是正确的方法。创建单个<VirtualHost>块几乎总是正确的方法。如果您有大量的虚拟主机,请考虑使用mod_vhost_alias自动创建这些主机。

mod_macro之类的模块对于动态创建大量虚拟主机也很有用。

如果您使用的托管服务不提供对服务器配置文件的访问权限,则可以使用mod_rewrite来创建 vitualhost,因此,您只能使用.htaccess文件进行配置。

请参阅使用 mod_rewrite 的虚拟主机文档,以获取有关在看起来仍然正确的方法下如何完成此操作的更多详细信息。

Simple Proxying

RewriteRule提供[P]标志以通过mod_proxy传递重写的 URI。

RewriteRule "^/?images(.*)" "http://imageserver.local/images$1" [P]

但是,在许多情况下,如上面的示例所示,当不需要实际的模式匹配时,ProxyPass伪指令是更好的选择。这里的示例可以表示为:

ProxyPass "/images/" "http://imageserver.local/images/"

请注意,无论您使用RewriteRule还是ProxyPass,您仍然需要使用ProxyPassReverse指令来捕获从后端服务器发出的重定向:

ProxyPassReverse "/images/" "http://imageserver.local/images/"

当同一范围内还有其他RewriteRule有效时,您可能需要使用RewriteRule,因为RewriteRule通常会在ProxyPass之前生效,因此可能会抢占您要完成的工作。

环境变量测试

mod_rewrite通常用于根据是否存在特定环境变量或请求 Headers 来执行特定操作。使用<If>可以更有效地完成此操作。

例如,考虑使用RewriteRule来强制使用规范的主机名的常见情况,例如www.example.com而不是example.com。可以使用<If>指令完成此操作,如下所示:

<If "req('Host') != 'www.example.com'">
    Redirect "/" "http://www.example.com/"
</If>

该技术可用于基于任何请求 Headers,响应 Headers 或环境变量来执行操作,在许多常见情况下可以替换mod_rewrite

尤其请参见表达评估文件,以概述可以在<If>部分和某些其他指令中使用的表达式类型。