Apache的ReWrite的应用(2)

发表于:2007-06-08来源:作者:点击数: 标签:
方案: 使用全局规则在空闲时间去除所有这些请求的前缀: 代码: RewriteEngine on RewriteRule ^/cgi-bin/imagemap(.*) $1 [PT] 在多个目录中搜索页面 说明: 有时会有必要使网站 服务器 在多个目录中搜索页面,对此,MultiViews或者其他技术无能为力。 方案:
方案:
使用全局规则在空闲时间去除所有这些请求的前缀:

代码:
RewriteEngine on
RewriteRule ^/cgi-bin/imagemap(.*) $1 [PT]


在多个目录中搜索页面
说明:
有时会有必要使网站服务器在多个目录中搜索页面,对此,MultiViews或者其他技术无能为力。

方案:
编制一个明确的规则集以搜索目录中的文件。

代码:
RewriteEngine on

# first try to find it in custom/...
# ...and if found stop and be happy:
RewriteCond /your/docroot/dir1/%{REQUEST_FILENAME} -f
RewriteRule ^(.+) /your/docroot/dir1/$1 [L]

# second try to find it in pub/...
# ...and if found stop and be happy:
RewriteCond /your/docroot/dir2/%{REQUEST_FILENAME} -f
RewriteRule ^(.+) /your/docroot/dir2/$1 [L]

# else go on for other Alias or ScriptAlias directives,
# etc.
RewriteRule ^(.+) - [PT]


按照URL的片段设置环境变量
说明:
如果希望保持请求之间的状态信息,但又不希望使用CGI来包装所有页面,而只通过分离URL中的有用信息来编码。

方案:
可以用一个规则集来分离出状态信息,并设置环境变量以备此后用于XSSI或CGI。如此,一个/foo/S=java/bar/的URL会被解析为/foo/bar/,而环境变量STATUS则被设置为"java"。

代码:
RewriteEngine on
RewriteRule ^(.*)/S=([^/]+)/(.*) $1/$3 [E=STATUS:$2]


虚拟用户主机
说明:
如果需要为用户username支持一个www.username.host.domain.com的主页,但不是用在此机器上建虚拟主机的方法,而是用仅在此机器上增加一个DNS记录的方法实现。

方案:
对HTTP/1.0的请求,这是无法实现的;但是对HTTP/1.1的在HTTP头中包含有主机名的请求,可以用以下规则集来内部地重写http://www.username.host.com/anypath为/home/username/anypath:

代码:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.[^.]+\.host\.com$
RewriteRule ^(.+) %{HTTP_HOST}$1 [C]
RewriteRule ^www\.([^.]+)\.host\.com(.*) /home/$1$2


为外来访问者重定向宿主目录
说明:
对不是来自本地域ourdomain.com的外来访问者的请求,重定向其宿主目录URL到另一个网站服务器www.somewhere.com,有时这种做法也会用在虚拟主机的上下文中。

方案:
只须一个重写条件:

代码:
RewriteEngine on
RewriteCond %{REMOTE_HOST} !^.+\.ourdomain\.com$
RewriteRule ^(/~.+) http://www.somewhere.com/$1 [R,L]


重定向失败的URL到其他网站服务器
说明:
如何重写URL以重定向对网站服务器A的失败请求到服务器B,是一个常见的问题。一般,可以用Perl写的CGI脚本通过ErrorDocument来解决,此外,还有mod_rewrite方案。但是须注意,这种方法的执行效率不如用ErrorDocument的CGI脚本!

方案:
第一种方案,有最好的性能而灵活性欠佳,出错概率小所以安全:

代码:
RewriteEngine on
RewriteCond /your/docroot/%{REQUEST_FILENAME} !-f
RewriteRule ^(.+) http://webserverB.dom/$1


但是其问题在于,它只对位于DocumentRoot中的页面有效。虽然可以增加更多的条件(比如同时还处理宿主目录,等等),但是还有一个更好的方法:

代码:
RewriteEngine on
RewriteCond %{REQUEST_URI} !-U
RewriteRule ^(.+) http://webserverB.dom/$1


这种方法使用了mod_rewrite提供的“向前参照(look-ahead)”的功能,是一种对所有URL类型都有效而且安全的方法。但是,对网站服务器的性能会有影响,所以如果网站服务器有一个强大的CPU,那就用这个方法。而在慢速机器上,可以用第一种方法,或者用性能更好的ErrorDocument CGI脚本。

扩展的重定向
说明:
有时候,我们会需要更多的对重定向URL的(有关字符转义机制方面的)控制。通常,Apache内核中的URL转义函数uri_escape()同时还会对anchor转义,即,类似"url#anchor"的URL,因此,你不能用mod_rewrite对此类URL直接重定向。那么如何实现呢?

方案:
必须用NPH-CGI脚本使它自己重定向,因为对NPH(non-parseable headers [无须解析的HTTP头])不会发生转义操作。首先,在针对服务器的配置中(应该位于所有重写规则的最后),引入一种新的URL类型xredirect::

代码:
RewriteRule ^xredirect:(.+) /path/to/nph-xredirect.cgi/$1 \
[T=application/x-httpd-cgi,L]


以强制所有带xredirect:前缀的URL被传送到如下的nph-xredirect.cgi程序:

代码:
#!/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 "\n";
print "\n";
print "\n";
print "\n";
print "\n";
print "
Moved Temporarily (EXTENDED)
\n";
print "The document has moved here.
\n";
print "\n";
print "\n";

##EOF##


这是一种可以重定向所有URL类型的方法,包括不被mod_rewrite直接支持的类型。所以,还可以这样重定向news:newsgroup:

代码:
RewriteRule ^anyurl xredirect:news:newsgroup


注意:无须对上述规则加[R]或[R,L],因为xredirect:会在稍后被其特殊的传送规则扩展。
文档访问的多路复用
说明:
你知道http://www.perl.com/CPAN的CPAN(Comprehensive Perl Archive Network)吗?它实现了一个重定向以提供,全世界的CPAN镜像中离访问者最近的一个FTP站点,也可以称之为FTP访问多路复用服务。CPAN是通过CGI脚本实现的,那么用mod_rewrite如何实现呢?

方案:
首先,我们注意到mod_rewrite从3.0.0版本开始,还可以重写"ftp:"类型。其次,对客户端顶级域名的路径最近的求取可以用RewriteMap实现。利用链式规则集,并用顶级域名作为查找多路复用地图的键,可以这样做:

代码:
RewriteEngine on
RewriteMap multiplex txt:/path/to/map.cxan
RewriteRule ^/CxAN/(.*) %{REMOTE_HOST}::$1 [C]
RewriteRule ^.+\.([a-zA-Z]+)::(.*)$ ${multiplex:$1|ftp.default.dom}$2 [R,L]

##
## 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##

依赖于时间的重写
说明:
在页面内容依时间不同而变化的场合,比如重定向特定页面,许多网管仍然采用CGI脚本的方法,如何用mod_rewrite来实现呢?

方案:
有许多类似TIME_xxx的变量可以用在重写条件中,利用STRING和=STRING的类型比较,并加以连接,就可以实现依赖于时间的重写:

(出处:Im286)

原文转自:http://www.ltesting.net