📄 mod_rewrite+.html
字号:
# now the rewriting rules
RewriteRule ^oldstuff\.html$ newstuff.html
</pre></div>
<p>上述例子中,对<code>/xyz/oldstuff.html</code>
的请求被正确地重写为物理的文件<code>/abc/def/newstuff.html</code>.</p>
<div class="note"><h3>For Apache Hackers</h3>
<p>以下列出了内部处理的详细步骤:</p>
<pre>
Request:
/xyz/oldstuff.html
Internal Processing:
/xyz/oldstuff.html -> /abc/def/oldstuff.html (per-server Alias)
/abc/def/oldstuff.html -> /abc/def/newstuff.html (per-dir RewriteRule)
/abc/def/newstuff.html -> /xyz/newstuff.html (per-dir RewriteBase)
/xyz/newstuff.html -> /abc/def/newstuff.html (per-server Alias)
Result:
/abc/def/newstuff.html
</pre>
<p>虽然这个过程看来很繁复,但是由于目录级重写的到来时机已经太晚了,
它不得不把这个(重写)请求重新注入到Apache核心中,所以Apache内部确实是这样处理的。
但是:它的开销并不象看起来的那样大,因为重新注入完全在Apache服务器内部进行,
而且这样的过程在Apache内部也为其他许多操作所使用。
所以,你可以充分信任其设计和实现是正确的。</p>
</div>
</div>
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="directive-section"><h2><a name="RewriteCond" id="RewriteCond">RewriteCond</a> <a name="rewritecond" id="rewritecond">指令</a></h2>
<table class="directive">
<tr><th><a href="directive-dict.html#Description">说明:</a></th><td>定义重写发生的条件
</td></tr>
<tr><th><a href="directive-dict.html#Syntax">语法:</a></th><td><code> RewriteCond
<em>TestString</em> <em>CondPattern</em></code></td></tr>
<tr><th><a href="directive-dict.html#Context">上下文:</a></th><td>服务器配置, 虚拟主机, 目录, .htaccess</td></tr>
<tr><th><a href="directive-dict.html#Override">覆盖项:</a></th><td>FileInfo</td></tr>
<tr><th><a href="directive-dict.html#Status">状态:</a></th><td>Extension</td></tr>
<tr><th><a href="directive-dict.html#Module">模块:</a></th><td>mod_rewrite</td></tr>
</table>
<p><code class="directive">RewriteCond</code>指令定义了一个规则的条件,即,在一个<code class="directive"><a href="#rewriterule">RewriteRule</a></code>指令之前有一个或多个<code class="directive">RewriteCond</code>指令。
条件之后的重写规则仅在当前URI与pattern匹配<strong>并且</strong>符合这些条件的时候才会起作用。</p>
<p><em>TestString</em>是一个纯文本的字符串,但是还可以包含下列可扩展的成分:</p>
<ul>
<li>
<strong>RewriteRule反向引用</strong>: 引用方法是
<p class="indent">
<strong><code>$N</code></strong>
</p>
(0 <= N <= 9)
引用当前(带有若干<code>RewriteCond</code>指令的)<code>RewriteRule</code>中的
与pattern匹配的分组成分(圆括号!)。
</li>
<li>
<strong>RewriteCond反向引用</strong>: 引用方法是
<p class="indent">
<strong><code>%N</code></strong>
</p>
(1 <= N <= 9)
引用当前若干<code>RewriteCond</code>条件中最后符合的条件中的分组成分(圆括号!)。
</li>
<li>
<strong>RewriteMap 扩展</strong>: 引用方法是
<p class="indent">
<strong><code>${mapname:key|default}</code></strong>
</p>
细节请参见<a href="#mapfunc">the documentation for
RewriteMap</a>。
</li>
<li>
<strong>服务器变量</strong>: 引用方法是
<p class="indent">
<strong><code>%{</code> <em>NAME_OF_VARIABLE</em>
<code>}</code></strong>
</p>
<em>NAME_OF_VARIABLE</em>可以是下表列出的字符串之一:
<table border="1" cellpadding="0" cellspacing="0" bordercolor="#CCCCCC">
<tr>
<th>HTTP headers:</th> <th>connection & request:</th> <th />
</tr>
<tr>
<td>
HTTP_USER_AGENT<br />
HTTP_REFERER<br />
HTTP_COOKIE<br />
HTTP_FORWARDED<br />
HTTP_HOST<br />
HTTP_PROXY_CONNECTION<br />
HTTP_ACCEPT<br />
</td>
<td>
REMOTE_ADDR<br />
REMOTE_HOST<br />
REMOTE_USER<br />
REMOTE_IDENT<br />
REQUEST_METHOD<br />
SCRIPT_FILENAME<br />
PATH_INFO<br />
QUERY_STRING<br />
AUTH_TYPE<br />
</td>
<td />
</tr>
<tr>
<th>server internals:</th> <th>system stuff:</th> <th>specials:</th>
</tr>
<tr>
<td>
DOCUMENT_ROOT<br />
SERVER_ADMIN<br />
SERVER_NAME<br />
SERVER_ADDR<br />
SERVER_PORT<br />
SERVER_PROTOCOL<br />
SERVER_SOFTWARE<br />
</td>
<td>
TIME_YEAR<br />
TIME_MON<br />
TIME_DAY<br />
TIME_HOUR<br />
TIME_MIN<br />
TIME_SEC<br />
TIME_WDAY<br />
TIME<br />
</td>
<td>
API_VERSION<br />
THE_REQUEST<br />
REQUEST_URI<br />
REQUEST_FILENAME<br />
IS_SUBREQ<br />
</td>
</tr>
</table>
<div class="note">
<p>这些都对应于类似命名的HTTP MIME头、Apache服务器的C变量以及Unix系统中的
<code>struct tm</code>字段,大多数都在其他的手册或者CGI规范中有所讲述。
而其中为mod_rewrite所特有的变量有:</p>
<dl>
<dt><code>IS_SUBREQ</code></dt>
<dd>如果正在处理的请求是一个子请求,它包含字符串"true",否则就是"false"。
模块为了解析URI中的附加文件,有可能会产生子请求。</dd>
<dt><code>API_VERSION</code></dt>
<dd>这是正在使用的httpd中(服务器和模块之间内部接口)的Apache模块API的版本,
其定义位于include/ap_mmn.h中。此模块版本对应于正在使用的Apache的版本
(比如,在Apache 1.3.14的发行版中,这个值是19990320:10)。
通常,对它感兴趣的是模块的作者。</dd>
<dt><code>THE_REQUEST</code></dt>
<dd>这是由浏览器发送给服务器的完整的HTTP请求行。(比如, "<code>GET
/index.html HTTP/1.1</code>"). 它不包含任何浏览器发送的附加头信息。</dd>
<dt><code>REQUEST_URI</code></dt>
<dd>这是在HTTP请求行中所请求的资源。(比如上述例子中的"/index.html".)</dd>
<dt><code>REQUEST_FILENAME</code></dt>
<dd>这是与请求相匹配的完整的本地文件系统的文件路径名或描述.</dd>
</dl>
</div>
</li>
</ul>
<p>特别注意事项:</p>
<ol>
<li>SCRIPT_FILENAME和REQUEST_FILENAME包含的值是相同的,<em>即</em>,
Apache服务器的内部<code>request_rec</code>结构中的<code>filename</code>字段。
第一个其实就是大家都知道的CGI变量名,而第二个则是(
包含了<code>request_rec</code>结构中的<code>uri</code>字段的)REQUEST_URI的一个副本,</li>
<li>特殊形式:
<code>%{ENV:variable}</code> 其中的<em>variable</em>可以是任何环境变量。
它是通过查找Apache内部结构得到的,
或者(如果没找到的话)是由Apache服务器进程通过<code>getenv()</code>得到的。</li>
<li>特殊形式:
<code>%{HTTP:header}</code> 其中的<em>header</em>可以是任何HTTP MIME头的名称。
它是通过查找HTTP请求得到的。比如: <code>%{HTTP:Proxy-Connection}</code>就是HTTP头
``<code>Proxy-Connection:</code>''的值.</li>
<li>特殊形式
<code>%{LA-U:variable}</code> 它是一个预设的值,
<em>variable</em>的最终值在执行一个内部的(基于URL的)子请求后决定。
在重写需要使用一个尚未有效的但是会在之后的API程序段中设置的变量的时候,就会使用这个方法。
比如,需要在服务器级配置(<code>httpd.conf</code>文件)中重写<code>REMOTE_USER</code>变量,
则,必须使用<code>%{LA-U:REMOTE_USER}</code>,因为此变量是由认证程序段设置的,
而这个程序段是在mod_rewrite所在的URL转译程序段<em>之后</em>才执行的。
但是,因为mod_rewrite是通过API修正程序段来实现目录级(<code>.htaccess</code> file)配置的,
而这个程序段在认证程序段<em>之前</em>就执行了,所以用<code>%{REMOTE_USER}</code>就可以了。</li>
<li>特殊形式:
<code>%{LA-F:variable}</code> 它是一个预设的值,
<em>variable</em>的最终值在执行一个内部的(基于文件名的)子请求后决定。
大多数情况下和上述的LA-U是相同的.</li>
</ol>
<p><em>CondPattern</em>是条件pattern,
<em>即</em>, 一个应用于当前实例<em>TestString</em>的正则表达式, <em>即</em>,
<em>TestString</em>将会被计算然后与<em>CondPattern</em>匹配.</p>
<p><strong>谨记:</strong> <em>CondPattern</em>是一个<em>兼容perl的正则表达式</em>,
但是还有若干增补:</p>
<ol>
<li>可以在pattern串中使用'<code>!</code>' 字符(惊叹号)来实现匹配的<strong>反转</strong>。</li>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -