Apache HTTP Server 版本 2.4
本文档是对 mod_rewrite
参考文档 的补充。它描述了关于 mod_rewrite
最重要的概念之一 - 也就是何时避免使用它。
mod_rewrite
应该被视为最后的手段,当其他替代方案都无法满足需求时才使用。当有更简单的替代方案时使用它会导致配置混乱、脆弱且难以维护。了解其他可用的替代方案是掌握 mod_rewrite
的非常重要的一步。
请注意,这些示例中的许多示例在您的特定服务器配置中无法直接使用,因此您需要理解它们,而不仅仅是将示例复制粘贴到您的配置中。
mod_rewrite
最适合使用的场景是,最佳解决方案需要访问服务器配置文件,而您没有访问权限。一些配置指令只能在服务器配置文件中使用。因此,如果您在只能使用 .htaccess 文件的托管环境中,您可能需要使用 mod_rewrite
。
mod_alias
提供了 Redirect
和 RedirectMatch
指令,它们提供了一种将一个 URL 重定向到另一个 URL 的方法。这种对一个 URL 或一类 URL 的简单重定向应该使用这些指令来完成,而不是使用 RewriteRule
。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.com
重定向到 www.example.com
,请参阅 规范主机名 食谱。
要将 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
来执行此任务可能是合适的。这是因为,当同一范围内存在 Redirect
和 RewriteRule
指令时,RewriteRule
指令将首先运行,无论它们在配置文件中的出现顺序如何。
在 http-to-https 重定向的情况下,如果您没有访问主服务器配置文件的权限,并且必须在 .htaccess
文件中执行此任务,则使用 RewriteRule
是合适的。
Alias
指令提供从 URI 到目录的映射 - 通常是您 DocumentRoot
之外的目录。虽然可以使用 mod_rewrite
来执行此映射,但 Alias
是首选方法,因为它更简单且性能更高。
Alias "/cats" "/var/www/virtualhosts/felines/htdocs"
当您没有访问服务器配置文件的权限时,使用 mod_rewrite
来执行此映射可能是合适的。Alias 只能在服务器或虚拟主机上下文中使用,而不能在 .htaccess
文件中使用。
如果您在服务器上启用了 Options FollowSymLinks
,符号链接将是另一种实现相同目的的方法。
虽然可以使用 mod_rewrite 处理虚拟主机,但这很少是正确的方法。创建单独的 <VirtualHost>
块几乎总是正确的方法。如果您有大量的虚拟主机,请考虑使用 mod_vhost_alias
自动创建这些主机。
诸如 mod_macro
之类的模块也有助于动态创建大量的虚拟主机。
如果您使用的是不提供您访问服务器配置文件的托管服务,并且您只能使用 .htaccess
文件进行配置,则使用 mod_rewrite
来创建虚拟主机可能是合适的。
有关如何使用 mod_rewrite 处理虚拟主机 的更多详细信息,请参阅该文档,如果这仍然看起来是正确的方法。
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
通常用于根据特定环境变量或请求头的存在与否来执行特定操作。这可以使用 <If>
指令更有效地完成。
例如,考虑一个常见的场景,其中 RewriteRule
用于强制使用规范主机名,例如 www.example.com
而不是 example.com
。这可以使用 <If>
指令完成,如下所示
<If "req('Host') != 'www.example.com'"> Redirect "/" "http://www.example.com/" </If>
此技术可用于根据任何请求头、响应头或环境变量来执行操作,从而在许多常见场景中取代 mod_rewrite
。