| <!DOCTYPE html SYSTEM "about:legacy-compat"> |
| <html lang="zh-cn"><head><META http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
| <meta content="width=device-width, initial-scale=1" name="viewport"> |
| <!-- |
| XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |
| This file is generated from xml source: DO NOT EDIT |
| XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |
| --> |
| <title>Apache mod_rewrite 技术细节 - Apache HTTP 服务器 版本 2.5</title> |
| <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet"> |
| <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size"> |
| <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css"><link rel="stylesheet" type="text/css" href="../style/css/prettify.css"> |
| <script src="../style/scripts/prettify.min.js"> |
| </script> |
| |
| <link href="../images/favicon.png" rel="shortcut icon"></head> |
| <body id="manual-page"><div id="page-header"> |
| <p class="menu"><a href="../mod/">模块</a> | <a href="../mod/quickreference.html">指令</a> | <a href="https://cwiki.apache.org/confluence/display/httpd/FAQ">常见问题</a> | <a href="../glossary.html">术语</a> | <a href="../sitemap.html">网站导航</a> | <a href="https://bz.apache.org/bugzilla/enter_bug.cgi?product=Apache%20httpd-2">Report a bug</a></p> |
| <p class="apache">Apache HTTP 服务器版本 2.5</p> |
| <img alt="" src="../images/feather.png"></div> |
| <div class="up"><a href="./"><img title="<-" alt="<-" src="../images/left.gif"></a></div> |
| <div id="path"> |
| <a href="https://www.apache.org/">Apache</a> > <a href="https://httpd.apache.org/">HTTP 服务器</a> > <a href="https://httpd.apache.org/docs/">文档</a> > <a href="../">版本 2.5</a> > <a href="./">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Apache mod_rewrite 技术细节</h1> |
| <button aria-label="Toggle language list" class="lang-toggle"><svg xmlns="http://www.w3.org/2000/svg" stroke-width="2" stroke="currentColor" fill="none" viewBox="0 0 24 24" height="16" width="16"><circle r="10" cy="12" cx="12"/><line y2="12" x2="22" y1="12" x1="2"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg></button> |
| <div class="toplang"> |
| <p><span>可用语言: </span><a href="../de/rewrite/tech.html" hreflang="de" rel="alternate" title="Deutsch"> de </a> | |
| <a href="../en/rewrite/tech.html" hreflang="en" rel="alternate" title="English"> en </a> | |
| <a href="../es/rewrite/tech.html" hreflang="es" rel="alternate" title="Español"> es </a> | |
| <a href="../fr/rewrite/tech.html" hreflang="fr" rel="alternate" title="Français"> fr </a> | |
| <a href="../ja/rewrite/tech.html" hreflang="ja" rel="alternate" title="Japanese"> ja </a> | |
| <a href="../ko/rewrite/tech.html" hreflang="ko" rel="alternate" title="Korean"> ko </a> | |
| <a href="../tr/rewrite/tech.html" hreflang="tr" rel="alternate" title="Türkçe"> tr </a> | |
| <a href="../zh-cn/rewrite/tech.html" title="Simplified Chinese"> zh-cn </a></p> |
| </div> |
| <div class="outofdate">此翻译可能过期。要了解最近的更改,请阅读英文版。</div> |
| |
| <p>本文档讨论 <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> 和 URL 匹配的一些技术细节。</p> |
| </div> |
| <div id="quickview"><ul id="toc"><li><img alt="" src="../images/down.gif"> <a href="#InternalAPI">API 阶段</a></li> |
| <li><img alt="" src="../images/down.gif"> <a href="#InternalRuleset">规则集处理</a></li> |
| </ul><h3>参见</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">模块文档</a></li><li><a href="intro.html">mod_rewrite 简介</a></li><li><a href="remapping.html">重定向和重映射</a></li><li><a href="access.html">访问控制</a></li><li><a href="vhosts.html">虚拟主机</a></li><li><a href="proxy.html">代理</a></li><li><a href="rewritemap.html">使用 RewriteMap</a></li><li><a href="advanced.html">高级技术</a></li><li><a href="avoid.html">何时不使用 mod_rewrite</a></li></ul></div> |
| <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif"></a></div> |
| <div class="section"> |
| <h2 id="InternalAPI">API 阶段 <a title="Permanent link" href="#InternalAPI" class="permalink">¶</a></h2> |
| |
| <p>Apache HTTP 服务器分多个阶段处理请求。在每个阶段, |
| 一个或多个模块可能被调用来处理请求生命周期的那个部分。 |
| 这些阶段包括 URL 到文件名转换、身份验证、授权、内容和日志记录等。 |
| (这不是一个详尽的列表。)</p> |
| |
| <p><code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> 在其中两个阶段(或通常所说的"钩子") |
| 中起作用,以影响 URL 的重写方式。</p> |
| |
| <p>首先,它使用 URL 到文件名转换钩子,该钩子在 HTTP |
| 请求被读取之后、但在任何授权开始之前触发。其次,它使用 Fixup 钩子, |
| 该钩子在授权阶段之后、在目录级配置文件(<code>.htaccess</code> 文件) |
| 被读取之后、但在内容处理程序被调用之前触发。</p> |
| |
| <p>当请求进入并确定了对应的服务器或虚拟主机后, |
| 重写引擎开始处理出现在服务器级配置中的所有 <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> |
| 指令。(即在主服务器配置文件和 <code class="directive"><a href="../mod/core.html#virtualhost"><Virtualhost></a></code> 配置段中。) |
| 这发生在 URL 到文件名转换阶段。</p> |
| |
| <p>几个步骤之后,一旦找到最终的数据目录, |
| 就会应用目录级配置指令(<code>.htaccess</code> 文件和 <code class="directive"><a href="../mod/core.html#directory"><Directory></a></code> 块)。 |
| 这发生在 Fixup 阶段。</p> |
| |
| <p>在每种情况下,<code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> 都会将 |
| <code>REQUEST_URI</code> 重写为新的 URL 或文件名。</p> |
| |
| <p>在目录级上下文中(即在 <code>.htaccess</code> 文件和 |
| <code>Directory</code> 块中),这些规则在 URL |
| 已经被转换为文件名之后才被应用。因此,<code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> |
| 最初用来与 <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> |
| 指令进行比较的 URL 路径是转换后的完整文件系统路径, |
| 其中当前目录路径(包括尾部斜杠)已从前面被移除。</p> |
| |
| <p>举例来说:如果规则位于 /var/www/foo/.htaccess 中, |
| 正在处理对 /foo/bar/baz 的请求,则表达式 ^bar/baz$ 将会匹配。</p> |
| |
| <p>如果在目录级上下文中进行了替换,将使用新的 URL |
| 发出新的内部子请求,重新开始请求阶段的处理。如果替换是相对路径, |
| <code class="directive"><a href="../mod/mod_rewrite.html#rewritebase">RewriteBase</a></code> |
| 指令决定在替换前面添加的 URL 路径前缀。在目录级上下文中, |
| 必须注意创建的规则最终(在未来某轮目录级重写处理中)不会执行替换, |
| 以避免循环。(参见 <a href="https://cwiki.apache.org/confluence/display/httpd/RewriteLooping">RewriteLooping</a> |
| 以进一步讨论此问题。)</p> |
| |
| <p>由于在目录级上下文中对 URL 进行了进一步操作, |
| 你需要注意在该上下文中以不同方式编写重写规则。特别要记住, |
| 前导目录路径将从你的重写规则所看到的 URL 中被去除。 |
| 请参考下面的示例以进一步说明。</p> |
| |
| <table class="bordered"> |
| |
| <tr> |
| <th>规则位置</th> |
| <th>规则</th> |
| </tr> |
| |
| <tr> |
| <td>VirtualHost 配置段</td> |
| <td>RewriteRule "^/images/(.+)\.jpg" "/images/$1.gif"</td> |
| </tr> |
| |
| <tr> |
| <td>文档根目录下的 .htaccess 文件</td> |
| <td>RewriteRule "^images/(.+)\.jpg" "images/$1.gif"</td> |
| </tr> |
| |
| <tr> |
| <td>images 目录下的 .htaccess 文件</td> |
| <td>RewriteRule "^(.+)\.jpg" "$1.gif"</td> |
| </tr> |
| |
| </table> |
| |
| <p>要更深入地了解 <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> 如何在不同上下文中操作 URL, |
| 你应该查阅重写期间生成的<a href="../mod/mod_rewrite.html#logging">日志条目</a>。</p> |
| |
| </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif"></a></div> |
| <div class="section"> |
| <h2 id="InternalRuleset">规则集处理 <a title="Permanent link" href="#InternalRuleset" class="permalink">¶</a></h2> |
| |
| <p>现在当 <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> 在这两个 API 阶段被触发时, |
| 它从其配置结构中读取已配置的规则集(该配置结构在服务器级上下文中于启动时创建, |
| 或在目录级上下文中于 Apache 内核的目录遍历过程中创建)。 |
| 然后使用包含的规则集(一条或多条规则及其条件)启动 URL 重写引擎。 |
| URL 重写引擎本身的操作在两种配置上下文中完全相同。 |
| 只有最终结果的处理方式不同。</p> |
| |
| <p>规则集中规则的顺序很重要,因为重写引擎以一种特殊的(且不太直观的) |
| 顺序处理它们。规则如下:重写引擎逐条遍历规则集中的规则 |
| (<code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> 指令), |
| 当某条规则匹配时,它会可选地遍历对应的条件 |
| (<code>RewriteCond</code> 指令)。由于历史原因, |
| 条件写在前面,因此控制流程有点绕。参见图 1 了解更多细节。</p> |
| <p class="figure"> |
| <img src="../images/rewrite_process_uri.png" alt="RewriteRule 和 RewriteCond 匹配流程"><br> |
| <dfn>图 1:</dfn>重写规则集的控制流程 |
| </p> |
| <p>首先,URL 与每条规则的<em>模式</em>进行匹配。如果匹配失败, |
| <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> 立即停止处理该规则,并继续处理下一条规则。 |
| 如果<em>模式</em>匹配成功,<code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> |
| 会查找对应的规则条件(RewriteCond 指令, |
| 在配置中紧接在 RewriteRule 之前出现)。 |
| 如果没有条件,则用从字符串<em>替换</em>构造的新值替换 URL, |
| 并继续其规则循环。但如果存在条件,则启动一个内部循环, |
| 按照条件列出的顺序处理它们。对于条件,逻辑是不同的: |
| 我们不是将模式与当前 URL 匹配。而是首先通过展开变量、 |
| 反向引用、映射查找<em>等</em>来创建一个字符串 <em>TestString</em>, |
| 然后尝试将 <em>CondPattern</em> 与之匹配。如果模式不匹配, |
| 则整组条件和对应规则都失败。如果模式匹配,则处理下一个条件, |
| 直到没有更多条件为止。如果所有条件都匹配, |
| 则继续用<em>替换</em>替换 URL。</p> |
| |
| </div></div> |
| <div class="bottomlang"> |
| <p><span>可用语言: </span><a href="../de/rewrite/tech.html" hreflang="de" rel="alternate" title="Deutsch"> de </a> | |
| <a href="../en/rewrite/tech.html" hreflang="en" rel="alternate" title="English"> en </a> | |
| <a href="../es/rewrite/tech.html" hreflang="es" rel="alternate" title="Español"> es </a> | |
| <a href="../fr/rewrite/tech.html" hreflang="fr" rel="alternate" title="Français"> fr </a> | |
| <a href="../ja/rewrite/tech.html" hreflang="ja" rel="alternate" title="Japanese"> ja </a> | |
| <a href="../ko/rewrite/tech.html" hreflang="ko" rel="alternate" title="Korean"> ko </a> | |
| <a href="../tr/rewrite/tech.html" hreflang="tr" rel="alternate" title="Türkçe"> tr </a> | |
| <a href="../zh-cn/rewrite/tech.html" title="Simplified Chinese"> zh-cn </a></p> |
| </div><div id="footer"> |
| <p class="apache">Copyright 2026 The Apache Software Foundation.<br>基于 <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> 许可证.</p> |
| <p class="menu"><a href="../mod/">模块</a> | <a href="../mod/quickreference.html">指令</a> | <a href="https://cwiki.apache.org/confluence/display/httpd/FAQ">常见问题</a> | <a href="../glossary.html">术语</a> | <a href="../sitemap.html">网站导航</a> | <a href="https://bz.apache.org/bugzilla/enter_bug.cgi?product=Apache%20httpd-2">Report a bug</a></p></div><script><!--//--><![CDATA[//><!-- |
| if (typeof(prettyPrint) !== 'undefined') { |
| prettyPrint(); |
| } |
| var langToggle = document.querySelector('.lang-toggle'); |
| var topLang = document.querySelector('.toplang'); |
| if (langToggle && topLang) { |
| langToggle.addEventListener('click', function() { topLang.classList.toggle('open'); }); |
| } |
| var qv = document.getElementById('quickview'); |
| if (qv) { |
| document.body.appendChild(qv); |
| var qvBtn = document.createElement('button'); |
| qvBtn.className = 'qv-toggle'; |
| qvBtn.setAttribute('aria-label', 'Toggle page navigation'); |
| qvBtn.innerHTML = '☰'; |
| document.body.appendChild(qvBtn); |
| qvBtn.addEventListener('click', function() { |
| var isOpen = qv.classList.toggle('open'); |
| if (isOpen) { |
| qv.style.top = window.scrollY + 10 + 'px'; |
| } |
| }); |
| window.addEventListener('scroll', function() { qv.classList.remove('open'); }); |
| } |
| //--><!]]></script> |
| </body></html> |