📄 rewriteguide.html.en
字号:
<p>This uses the URL look-ahead feature of <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>. The result is that this will work for all types of URLs and is a safe way. But it does a performance impact on the webserver, because for every request there is one more internal subrequest. So, if your webserver runs on a powerful CPU, use this one. If it is a slow machine, use the first approach or better a <code class="directive"><a href="../mod/core.html#errordocument">ErrorDocument</a></code> CGI-script.</p> </dd> </dl> <h3>Extended Redirection</h3> <dl> <dt>Description:</dt> <dd> <p>Sometimes we need more control (concerning the character escaping mechanism) of URLs on redirects. Usually the Apache kernels URL escape function also escapes anchors, i.e. URLs like "<code>url#anchor</code>". You cannot use this directly on redirects with <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> because the <code>uri_escape()</code> function of Apache would also escape the hash character. How can we redirect to such a URL?</p> </dd> <dt>Solution:</dt> <dd> <p>We have to use a kludge by the use of a NPH-CGI script which does the redirect itself. Because here no escaping is done (NPH=non-parseable headers). First we introduce a new URL scheme <code>xredirect:</code> by the following per-server config-line (should be one of the last rewrite rules):</p><div class="example"><pre>RewriteRule ^xredirect:(.+) /path/to/nph-xredirect.cgi/$1 \ [T=application/x-httpd-cgi,L]</pre></div> <p>This forces all URLs prefixed with <code>xredirect:</code> to be piped through the <code>nph-xredirect.cgi</code> program. And this program just looks like:</p><div class="example"><pre>#!/path/to/perl#### nph-xredirect.cgi -- NPH/CGI script for extended redirects## Copyright (c) 1997 Ralf S. Engelschall, All Rights Reserved.##$| = 1;$url = $ENV{'PATH_INFO'};print "HTTP/1.0 302 Moved Temporarily\n";print "Server: $ENV{'SERVER_SOFTWARE'}\n";print "Location: $url\n";print "Content-type: text/html\n";print "\n";print "<html>\n";print "<head>\n";print "<title>302 Moved Temporarily (EXTENDED)</title>\n";print "</head>\n";print "<body>\n";print "<h1>Moved Temporarily (EXTENDED)</h1>\n";print "The document has moved <a HREF=\"$url\">here</a>.<p>\n";print "</body>\n";print "</html>\n";##EOF##</pre></div> <p>This provides you with the functionality to do redirects to all URL schemes, i.e. including the one which are not directly accepted by <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>. For instance you can now also redirect to <code>news:newsgroup</code> via</p><div class="example"><pre>RewriteRule ^anyurl xredirect:news:newsgroup</pre></div> <div class="note">Notice: You have not to put <code>[R]</code> or <code>[R,L]</code> to the above rule because the <code>xredirect:</code> need to be expanded later by our special "pipe through" rule above.</div> </dd> </dl> <h3>Archive Access Multiplexer</h3> <dl> <dt>Description:</dt> <dd> <p>Do you know the great CPAN (Comprehensive Perl Archive Network) under <a href="http://www.perl.com/CPAN">http://www.perl.com/CPAN</a>? This does a redirect to one of several FTP servers around the world which carry a CPAN mirror and is approximately near the location of the requesting client. Actually this can be called an FTP access multiplexing service. While CPAN runs via CGI scripts, how can a similar approach implemented via <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>?</p> </dd> <dt>Solution:</dt> <dd> <p>First we notice that from version 3.0.0 <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> can also use the "<code>ftp:</code>" scheme on redirects. And second, the location approximation can be done by a <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> over the top-level domain of the client. With a tricky chained ruleset we can use this top-level domain as a key to our multiplexing map.</p><div class="example"><pre>RewriteEngine onRewriteMap multiplex txt:/path/to/map.cxanRewriteRule ^/CxAN/(.*) %{REMOTE_HOST}::$1 [C]RewriteRule ^.+\.<strong>([a-zA-Z]+)</strong>::(.*)$ ${multiplex:<strong>$1</strong>|ftp.default.dom}$2 [R,L]</pre></div><div class="example"><pre>#### map.cxan -- Multiplexing Map for CxAN##de ftp://ftp.cxan.de/CxAN/uk ftp://ftp.cxan.uk/CxAN/com ftp://ftp.cxan.com/CxAN/ :##EOF##</pre></div> </dd> </dl> <h3>Time-Dependent Rewriting</h3> <dl> <dt>Description:</dt> <dd> <p>When tricks like time-dependent content should happen a lot of webmasters still use CGI scripts which do for instance redirects to specialized pages. How can it be done via <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>?</p> </dd> <dt>Solution:</dt> <dd> <p>There are a lot of variables named <code>TIME_xxx</code> for rewrite conditions. In conjunction with the special lexicographic comparison patterns <code><STRING</code>, <code>>STRING</code> and <code>=STRING</code> we can do time-dependent redirects:</p><div class="example"><pre>RewriteEngine onRewriteCond %{TIME_HOUR}%{TIME_MIN} >0700RewriteCond %{TIME_HOUR}%{TIME_MIN} <1900RewriteRule ^foo\.html$ foo.day.htmlRewriteRule ^foo\.html$ foo.night.html</pre></div> <p>This provides the content of <code>foo.day.html</code> under the URL <code>foo.html</code> from <code>07:00-19:00</code> and at the remaining time the contents of <code>foo.night.html</code>. Just a nice feature for a homepage...</p> </dd> </dl> <h3>Backward Compatibility for YYYY to XXXX migration</h3> <dl> <dt>Description:</dt> <dd> <p>How can we make URLs backward compatible (still existing virtually) after migrating <code>document.YYYY</code> to <code>document.XXXX</code>, e.g. after translating a bunch of <code>.html</code> files to <code>.phtml</code>?</p> </dd> <dt>Solution:</dt> <dd> <p>We just rewrite the name to its basename and test for existence of the new extension. If it exists, we take that name, else we rewrite the URL to its original state.</p><div class="example"><pre># backward compatibility ruleset for# rewriting document.html to document.phtml# when and only when document.phtml exists# but no longer document.htmlRewriteEngine onRewriteBase /~quux/# parse out basename, but remember the factRewriteRule ^(.*)\.html$ $1 [C,E=WasHTML:yes]# rewrite to document.phtml if existsRewriteCond %{REQUEST_FILENAME}.phtml -fRewriteRule ^(.*)$ $1.phtml [S=1]# else reverse the previous basename cutoutRewriteCond %{ENV:WasHTML} ^yes$RewriteRule ^(.*)$ $1.html</pre></div> </dd> </dl> </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div><div class="section"><h2><a name="content" id="content">Content Handling</a></h2> <h3>From Old to New (intern)</h3> <dl> <dt>Description:</dt> <dd> <p>Assume we have recently renamed the page <code>foo.html</code> to <code>bar.html</code> and now want to provide the old URL for backward compatibility. Actually we want that users of the old URL even not recognize that the pages was renamed.</p> </dd> <dt>Solution:</dt> <dd> <p>We rewrite the old URL to the new one internally via the following rule:</p><div class="example"><pre>RewriteEngine onRewriteBase /~quux/RewriteRule ^<strong>foo</strong>\.html$ <strong>bar</strong>.html</pre></div> </dd> </dl> <h3>From Old to New (extern)</h3> <dl> <dt>Description:</dt> <dd> <p>Assume again that we have recently renamed the page <code>foo.html</code> to <code>bar.html</code> and now want to provide the old URL for backward compatibility. But this time we want that the users of the old URL get hinted to the new one, i.e. their browsers Location field should change, too.</p> </dd> <dt>Solution:</dt> <dd> <p>We force a HTTP redirect to the new URL which leads to a change of the browsers and thus the users view:</p><div class="example"><pre>RewriteEngine onRewriteBase /~quux/RewriteRule ^<strong>foo</strong>\.html$ <strong>bar</strong>.html [<strong>R</strong>]</pre></div> </dd> </dl> <h3>Browser Dependent Content</h3> <dl> <dt>Description:</dt> <dd> <p>At least for important top-level pages it is sometimes necessary to provide the optimum of browser dependent content, i.e. one has to provide a maximum version for the latest Netscape variants, a minimum version for the Lynx browsers and a average feature version for all others.</p> </dd> <dt>Solution:</dt> <dd> <p>We cannot use content negotiation because the browsers do not provide their type in that form. Instead we have to act on the HTTP header "User-Agent". The following condig does the following: If the HTTP header "User-Agent" begins with "Mozilla/3", the page <code>foo.html</code> is rewritten to <code>foo.NS.html</code> and and the rewriting stops. If the browser is "Lynx" or "Mozilla" of version 1 or 2 the URL becomes <code>foo.20.html</code>. All other browsers receive page <code>foo.32.html</code>. This is done by the following ruleset:</p><div class="example"><pre>RewriteCond %{HTTP_USER_AGENT} ^<strong>Mozilla/3</strong>.*RewriteRule ^foo\.html$ foo.<strong>NS</strong>.html [<strong>L</strong>]RewriteCond %{HTTP_USER_AGENT} ^<strong>Lynx/</strong>.* [OR]RewriteCond %{HTTP_USER_AGENT} ^<strong>Mozilla/[12]</strong>.*RewriteRule ^foo\.html$ foo.<strong>20</strong>.html [<strong>L</strong>]RewriteRule ^foo\.html$ foo.<strong>32</strong>.html [<strong>L</strong>]</pre></div> </dd> </dl> <h3>Dynamic Mirror</h3> <dl> <dt>Description:</dt> <dd> <p>Assume there are nice webpages on remote hosts we want to bring into our namespace. For FTP servers we would use the <code>mirror</code> program which actually maintains an explicit up-to-date copy of the remote data on the local machine. For a webserver we could use the program <code>webcopy</code> which acts similar via HTTP. But both techniques have one major drawback: The local copy is always just as up-to-date as often we run the program. It would be much better if the mirror is not a static one we have to establish explicitly. Instead we want a dynamic mirror with data which gets updated automatically when there is need (updated data on the remote host).</p> </dd> <dt>Solution:</dt> <dd> <p>To provide this feature we map the remote webpage or even the complete remote webarea to our namespace by the use of the <dfn>Proxy Throughput</dfn> feature (flag <code>[P]</code>):</p><div class="example"><pre>RewriteEngine onRewriteBase /~quux/RewriteRule ^<strong>hotsheet/</strong>(.*)$ <strong>http://www.tstimpreso.com/hotsheet/</strong>$1 [<strong>P</strong>]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -