| <?xml version="1.0" encoding="UTF-8" ?> |
| <!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd"> |
| <?xml-stylesheet type="text/xsl" href="../style/manual.zh-cn.xsl"?> |
| <!-- English Revision: 1933071:1934233 (outdated) --> |
| |
| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| |
| <manualpage metafile="avoid.xml.meta"> |
| <parentdocument href="./">Rewrite</parentdocument> |
| |
| <title>何时不使用 mod_rewrite</title> |
| |
| <summary> |
| |
| <p>本文档是 <module>mod_rewrite</module> |
| <a href="../mod/mod_rewrite.html">参考文档</a>的补充。它描述了关于 |
| <module>mod_rewrite</module> 最重要的概念之一—— |
| 即何时应避免使用它。</p> |
| |
| <p><module>mod_rewrite</module> 应被视为最后的手段, |
| 当其他替代方案不能满足需求时才使用。在有更简单替代方案的情况下使用它, |
| 会导致配置混乱、脆弱且难以维护。 |
| 了解有哪些替代方案可用是掌握 <module>mod_rewrite</module> 的重要一步。</p> |
| |
| <p>请注意,这些示例中的许多不会在你的特定服务器配置中直接生效, |
| 因此理解它们非常重要,而不仅仅是将示例复制粘贴到你的配置中。</p> |
| |
| <p>最常见的适合使用 <module>mod_rewrite</module> 的情况是, |
| 最佳解决方案需要访问服务器配置文件,而你没有该访问权限。 |
| 某些配置指令只能在服务器配置文件中使用。因此, |
| 如果你处于只能使用 .htaccess 文件的托管环境中, |
| 你可能需要借助 <module>mod_rewrite</module>。</p> |
| |
| </summary> |
| <seealso><a href="../mod/mod_rewrite.html">模块文档</a></seealso> |
| <seealso><a href="intro.html">mod_rewrite 简介</a></seealso> |
| <seealso><a href="remapping.html">重定向和重映射</a></seealso> |
| <seealso><a href="access.html">访问控制</a></seealso> |
| <seealso><a href="vhosts.html">虚拟主机</a></seealso> |
| <seealso><a href="proxy.html">代理</a></seealso> |
| <seealso><a href="rewritemap.html">使用 RewriteMap</a></seealso> |
| <seealso><a href="advanced.html">高级技术</a></seealso> |
| <!--<seealso><a href="avoid.html">何时不使用 mod_rewrite</a></seealso>--> |
| |
| <section id="redirect"> |
| <title>简单重定向</title> |
| |
| <p><module>mod_alias</module> 提供了 <directive |
| module="mod_alias">Redirect</directive> 和 <directive |
| module="mod_alias">RedirectMatch</directive> 指令, |
| 它们提供了将一个 URL 重定向到另一个 URL 的方法。 |
| 这种简单的将一个 URL 或一类 URL 重定向到其他地方的操作, |
| 应使用这些指令而不是 |
| <directive module="mod_rewrite">RewriteRule</directive> 来完成。 |
| <code>RedirectMatch</code> 允许你在重定向条件中包含正则表达式, |
| 提供了使用 <code>RewriteRule</code> 的许多好处。</p> |
| |
| <p><code>RewriteRule</code> 的一个常见用途是重定向整类 URL。 |
| 例如,<code>/one</code> 目录中的所有 URL 必须重定向到 |
| <code>http://one.example.com/</code>,或者所有 <code>http</code> |
| 请求必须重定向到 <code>https</code>。</p> |
| |
| <p>这些情况更适合使用 <code>Redirect</code> 指令处理。 |
| 请记住,<code>Redirect</code> 会保留路径信息。也就是说, |
| 对 URL <code>/one</code> 的重定向也会重定向其下的所有 URL, |
| 例如 <code>/one/two.html</code> 和 <code>/one/three/four.html</code>。</p> |
| |
| <p>要将 <code>/one</code> 下的 URL 重定向到 |
| <code>http://one.example.com</code>,请执行以下操作:</p> |
| |
| <highlight language="config"> |
| Redirect "/one/" "http://one.example.com/" |
| </highlight> |
| |
| <p>要将一个主机名重定向到另一个,例如将 |
| <code>example.com</code> 重定向到 <code>www.example.com</code>, |
| 请参阅<a href="remapping.html#canonicalhost">规范主机名</a>方案。</p> |
| |
| <p>要将 <code>http</code> URL 重定向到 <code>https</code>, |
| 请执行以下操作:</p> |
| |
| <highlight language="config"> |
| <VirtualHost *:80> |
| ServerName www.example.com |
| Redirect "/" "https://www.example.com/" |
| </VirtualHost> |
| |
| <VirtualHost *:443> |
| ServerName www.example.com |
| # ... SSL 配置放在这里 |
| </VirtualHost> |
| </highlight> |
| |
| <p>当同一作用域中存在其他 <code>RewriteRule</code> 指令时, |
| 使用 <code>RewriteRule</code> 来完成此任务可能是合适的。 |
| 这是因为,当 <code>Redirect</code> 和 <code>RewriteRule</code> |
| 指令在同一作用域中时,无论它们在配置文件中的出现顺序如何, |
| <code>RewriteRule</code> 指令都会先执行。</p> |
| |
| <p>对于 <em>http 到 https</em> 的重定向, |
| 当你无权访问主服务器配置文件, |
| 而被迫在 <code>.htaccess</code> 文件中执行此任务时, |
| 使用 <code>RewriteRule</code> 是合适的。</p> |
| |
| </section> |
| |
| <section id="alias"><title>URL 别名</title> |
| <p><directive module="mod_alias">Alias</directive> |
| 指令提供了从 URI 到目录的映射——通常是 |
| <directive module="core">DocumentRoot</directive> 之外的目录。 |
| 虽然可以使用 <module>mod_rewrite</module> 执行此映射, |
| 但出于简便性和性能原因,<directive module="mod_alias">Alias</directive> |
| 是首选方法。</p> |
| |
| <example><title>使用 Alias</title> |
| <highlight language="config"> |
| Alias "/cats" "/var/www/virtualhosts/felines/htdocs" |
| </highlight> |
| </example> |
| |
| <p> |
| 当你无权访问服务器配置文件时,使用 <module>mod_rewrite</module> |
| 执行此映射可能是合适的。Alias 只能在服务器或虚拟主机上下文中使用, |
| 不能在 <code>.htaccess</code> 文件中使用。 |
| </p> |
| |
| <p>如果你的服务器启用了 <code>Options FollowSymLinks</code>, |
| 符号链接将是实现同样目标的另一种方式。</p> |
| </section> |
| |
| <section id="vhosts"><title>虚拟主机</title> |
| <p>虽然可以<a href="vhosts.html">使用 mod_rewrite 处理虚拟主机</a>, |
| 但这很少是正确的方式。创建单独的 |
| <directive module="core" type="section">VirtualHost</directive> |
| 块几乎总是正确的做法。如果你有大量的虚拟主机, |
| 可以考虑使用 <module>mod_vhost_alias</module> 来自动创建这些主机。</p> |
| |
| <p><module>mod_macro</module> 等模块对于动态创建大量虚拟主机也很有用。</p> |
| |
| <p>当你使用的托管服务不提供服务器配置文件的访问权限, |
| 你只能使用 <code>.htaccess</code> 文件进行配置时, |
| 使用 <module>mod_rewrite</module> 创建虚拟主机可能是合适的。</p> |
| |
| <p>请参阅<a href="vhosts.html">使用 mod_rewrite 的虚拟主机</a>文档, |
| 了解如何实现此目的(如果这仍然看起来是正确的方法)。</p> |
| |
| </section> |
| |
| <section id="proxy"><title>简单代理</title> |
| |
| <p><directive module="mod_rewrite">RewriteRule</directive> 提供了 <a |
| href="flags.html#flag_p">[P]</a> 标志,用于将重写后的 URI 通过 |
| <module>mod_proxy</module> 传递。</p> |
| |
| <highlight language="config"> |
| RewriteRule "^/?images(.*)" "http://imageserver.local/images$1" [P] |
| </highlight> |
| |
| <p>但是,在许多情况下,当不需要实际的模式匹配时(如上面的示例所示), |
| <directive module="mod_proxy">ProxyPass</directive> 指令是更好的选择。 |
| 上面的示例可以表示为:</p> |
| |
| <highlight language="config"> |
| ProxyPass "/images/" "http://imageserver.local/images/" |
| </highlight> |
| |
| <p>请注意,无论你使用 |
| <directive module="mod_rewrite">RewriteRule</directive> 还是 |
| <directive module="mod_proxy">ProxyPass</directive>, |
| 你仍然需要使用 |
| <directive module="mod_proxy">ProxyPassReverse</directive> |
| 指令来捕获后端服务器发出的重定向:</p> |
| |
| <highlight language="config"> |
| ProxyPassReverse "/images/" "http://imageserver.local/images/" |
| </highlight> |
| |
| <p>当同一作用域中有其他 <code>RewriteRule</code> 生效时, |
| 你可能需要使用 <code>RewriteRule</code> 代替, |
| 因为 <code>RewriteRule</code> 通常会在 <code>ProxyPass</code> |
| 之前生效,可能会抢先处理你要完成的操作。</p> |
| |
| </section> |
| |
| <section id="setenv"><title>环境变量测试</title> |
| |
| <p><module>mod_rewrite</module> 经常用于根据特定环境变量或请求头 |
| 是否存在来执行特定操作。使用 |
| <directive module="core" type="section">If</directive> |
| 指令可以更高效地完成此操作。</p> |
| |
| <p>例如,考虑使用 <directive>RewriteRule</directive> |
| 来强制使用规范主机名(如 <code>www.example.com</code> 而不是 |
| <code>example.com</code>)的常见场景。可以使用 |
| <directive module="core" type="section">If</directive> |
| 指令来完成,如下所示:</p> |
| |
| <highlight language="config"> |
| <If "req('Host') != 'www.example.com'"> |
| Redirect "/" "http://www.example.com/" |
| </If> |
| </highlight> |
| |
| <p>此技术可用于根据任何请求头、响应头或环境变量执行操作, |
| 在许多常见场景中替代 <module>mod_rewrite</module>。</p> |
| |
| <p>特别请参阅<a href="../expr.html">表达式求值文档</a>, |
| 了解在 <directive module="core" type="section">If</directive> |
| 配置段和某些其他指令中可以使用哪些类型的表达式。</p> |
| |
| </section> |
| |
| </manualpage> |