Apache URL重定向指南(转)

上一篇 / 下一篇  2007-05-12 10:28:27 / 个人分类:php

mod_rewrite入门

Apache mod_rewrite模块是一个处理URL而又极为复杂的模块,使用mod_rewrite你可处理所有和URL有关的问题,你所付出的就是花时间去了解mod_rewrite的复杂架构,一般初学者都很难实时理解mod_rewrite的用法,有时Apache专家也要mod_rewrite来发展Apache的新功能。

换句话说,当你成功使用mod_rewrite做到你期望的东西,就不要试图再接触mod_rewrite了,因为mod_rewrite的功能实在过于强大。本章的例子会介绍几个成功的例子给你摸索,不像FAQ形式般把你的问题解答。

实用解决方法

这里还有很多未被发掘的解决方法,请大家耐心地学习如何使用mod_rewrite

注意:由于各人的服务器的配置都有所不同,你可能要更改设定来测试以下例子,例如使用mod_aliasmod_userdir时要加上[PT],或者使用.htaccess来重定向而非主设定文件等,请尽量理解各例子如何运作,不要生吞活剥地背诵。

URL规划

正规URL

描述:

在某些网页服务器中,一项资源可能会有数个URL,通常都会公布一正规URL(即真正发放的URL),其它URL都会被视为快捷方式或只供内部使用等,无论用户在使用快捷方式或正规URL,用户最后所重定向到的URL必需为正规。

方法:

我们可将所有非正规的URL重定向至正规的URL中,以下例子把非正规的「/~user」换成正规的「/u/user」,并且加上「/」号结尾。.

RewriteRule  ^/~([^/]+)/?(.*)   /u/$1/$2 [R]
RewriteRule  ^/([uge])/([^/]+)$ /$1/$2/  [R]

正规主机名称

描述:

(省略)

方法:

RewriteCond %{HTTP_HOST}  !^fully\.qualified\.domain\.name [NC]
RewriteCond %{HTTP_HOST}  !^$
RewriteCond %{SERVER_PORT} !^80$
RewriteRule ^/(.*)        http://fully.qualified.domain.name:%{SERVER_PORT}/$1 [L,R]
RewriteCond %{HTTP_HOST}  !^fully\.qualified\.domain\.name [NC]
RewriteCond %{HTTP_HOST}  !^$
RewriteRule ^/(.*)        http://fully.qualified.domain.name/$1 [L,R]

DocumentRoot被移动

描述:

URL的「/」通常都会映像到DocumentRoot上,但DocumentRoot有时并非重始就限定在某个目录上,它可能只是一个或多个目录的对照而矣。例如我们的内联网址为/e/www/(WWW的主目录)/e/sww/(内联网的主目录)等等,因为所有的网页资料都放在/e/www/目录内,我们要确定所有内嵌的图像都能正确显示。

方法:

我们只要把「/」重定向至「/e/www/」,用mod_rewrite来解决比用mod_alias来解决更为简洁,因为URL别名只会比较URL的前部分,但重定向因可能涉及另一台服务器而需要不同的前缀部分(前缀部分已受DocumentRoot限制),所以mod_rewrite是最好的解决方法::

RewriteEngine on
RewriteRule  ^/$ /e/www/ [R]

结尾斜线问题

描述:

每个网主都曾受到结尾斜线问题的折磨,若在URL中没有结尾斜线,服务器就会认为URL无效并返回错误,因为服务器会根据/~quux/foo去寻找foo这个档案,而非显示这个目录。其实很多时候,这问题应留待用户自己加「/」去解决,但有时你也可以完成步骤。例如你做了多次URL重定向,而目的地为一个CGI程序。

方法:

最直观的方法就是令Apache自动加上「/」,使用外部重定向令浏览器能正确找到档案,若我们只做内部重定向,就只能正确显示目录页,在这目录页的图像文件会因相对URL的问题而找不到。例如我们请求/~quux/foo/index.htmlimage.gif时,重定向后会变成/~quux/image.gif

所以我们应使用以下方法:

RewriteEngine on
RewriteBase   /~quux/
RewriteRule   ^foo$ foo/ [R]

这方法也适用于.htaccess文件在各目录内设定,但这设定会覆盖原先主配置文件。

RewriteEngine on
RewriteBase   /~quux/
RewriteCond   %{REQUEST_FILENAME} -d
RewriteRule   ^(.+[^/])$          $1/ [R]

利用均一的URL版面规划网络群组

描述:

所有的网页服务器都有相同的URL版面,即无论用户向哪个主机发出请求URL,用户都会接收到相同的网页,使URL独立于服务器本身。我们的目的在于如何在Apache服务器不能响应时,都能有一个常规(而又独立于服务器运作)的网页传送给用户,设立网络群组可将这网页送至远程。

方法:

首先,服务器需要一外部文件把网站的用户、用户组及其它资料存储,这文件的格式如下

user1 server_of_user1
user2 server_of_user2
:     :

把以上资料存入map.xxx-to-host。然后指示服务器把URL重定向,由

/u/user/anypath
/g/group/anypath
/e/entity/anypath

http://physical-host/u/user/anypath
http://physical-host/g/group/anypath
http://physical-host/e/entity/anypath

当服务器接收到不正确的URL时,服务器会跟随以下指示把URL映像到特定的档案(若URL并没有相对应的记录,就会重定向至 server0 上):

RewriteEngine on
 
RewriteMap     user-to-host  txt:/path/to/map.user-to-host
RewriteMap    group-to-host  txt:/path/to/map.group-to-host
RewriteMap   entity-to-host  txt:/path/to/map.entity-to-host
 
RewriteRule  ^/u/([^/]+)/?(.*)  http://${user-to-host:$1|server0}/u/$1/$2
RewriteRule  ^/g/([^/]+)/?(.*) http://${group-to-host:$1|server0}/g/$1/$2
RewriteRule  ^/e/([^/]+)/?(.*) http://${entity-to-host:$1|server0}/e/$1/$2
 
RewriteRule  ^/([uge])/([^/]+)/?$         /$1/$2/.www/
RewriteRule  ^/([uge])/([^/]+)/([^.]+.+)  /$1/$2/.www/$3\

把主目录移到新的网页服务器

描述:

有很多网主都有以下问题:在升级时把所有用户主目录由旧的服务器移到新的服务器上。

方法:

使用mod_rewrite可以简单地解决这问题,把所有/~user/anypathURL重定向至http://newserver/~user/anypath

RewriteEngine on
RewriteRule  ^/~(.+) http://newserver/~$1 [R,L]

结构化用户主目录

描述:

拥有大量用户的主机通常都会把用户目录规划好,将这些目录归入一个父目录中,然后再将用户的第一个字母作该用户的父目录,例如/~foo/anypath将会是/home/f/foo/.www/anypath,而/~bar/anypath就是/home/b/bar/.www/anypath

方法:

按以下指令将URL直接对映到档案系统中。

RewriteEngine on
RewriteRule  ^/~(([a-z])[a-z0-9]+)(.*) /home/$2/$1/.www$3

重新组织档案系统

描述:

这是一个麻烦的例子:在不用更动现有目录结构下,使用RewriteRules来显示整个目录结构。背景:net.sw是一个装满Unix免费软件的资料夹,并以下列结构存储:

drwxrwxr-x  2 netsw users   512 Aug 3 18:39 Audio/
drwxrwxr-x  2 netsw users   512 Jul 9 14:37 Benchmark/
drwxrwxr-x 12 netsw users   512 Jul 9 00:34 Crypto/
drwxrwxr-x  5 netsw users   512 Jul 9 00:41 Database/
drwxrwxr-x  4 netsw users   512 Jul 30 19:25 Dicts/
drwxrwxr-x 10 netsw users   512 Jul 9 01:54 Graphic/
drwxrwxr-x  5 netsw users   512 Jul 9 01:58 Hackers/
drwxrwxr-x  8 netsw users   512 Jul 9 03:19 InfoSys/
drwxrwxr-x  3 netsw users   512 Jul 9 03:21 Math/
drwxrwxr-x  3 netsw users   512 Jul 9 03:24 Misc/
drwxrwxr-x  9 netsw users   512 Aug 1 16:33 Network/
drwxrwxr-x  2 netsw users   512 Jul 9 05:53 Office/
drwxrwxr-x  7 netsw users   512 Jul 9 09:24 SoftEng/
drwxrwxr-x  7 netsw users   512 Jul 9 12:17 System/
drwxrwxr-x 12 netsw users   512 Aug 3 20:15 Typesetting/
drwxrwxr-x 10 netsw users   512 Jul 9 14:08 X11/

我们打算把这个资料夹公开,而且希望直接地显示这资料夹的目录结构,但是我们又不想更改现有目录架构来迁就,加上我们打算开放给FTP,所以不想加入任何网页或CGI程序到这个资料夹中。

方法:

本方法分为两部分:第一部份是编写一系列的CGI程序来显示目录结构,这例子会把CGI和刚才的资料夹放进/e/netsw/.www/

-rw-r--r--  1 netsw users   1318 Aug 1 18:10 .wwwacl
drwxr-xr-x 18 netsw users    512 Aug 5 15:51 DATA/
-rw-rw-rw-  1 netsw users 372982 Aug 5 16:35 LOGFILE
-rw-r--r--  1 netsw users    659 Aug 4 09:27 TODO
-rw-r--r--  1 netsw users   5697 Aug 1 18:01 netsw-about.html
-rwxr-xr-x  1 netsw users    579 Aug 2 10:33 netsw-access.pl
-rwxr-xr-x  1 netsw users   1532 Aug 1 17:35 netsw-changes.cgi
-rwxr-xr-x  1 netsw users   2866 Aug 5 14:49 netsw-home.cgi
drwxr-xr-x  2 netsw users    512 Jul 8 23:47 netsw-img/
-rwxr-xr-x  1 netsw users  24050 Aug 5 15:49 netsw-lsdir.cgi
-rwxr-xr-x  1 netsw users   1589 Aug 3 18:43 netsw-search.cgi
-rwxr-xr-x  1 netsw users   1885 Aug 1 17:41 netsw-tree.cgi
-rw-r--r--  1 netsw users    234 Jul 30 16:35 netsw-unlimit.lst

DATA/子目录就是刚才的资料夹,net.sw内的软件会经rdist程序来自动更新。第二部份将这资料夹和新建立的CGI、网页配合,我们想将DATA/稳藏起来,而在用户请求不同URL时执行正确的CGI程序来显示。先将/net.sw/URL重定向至/e/netsw

RewriteRule ^net.sw$      net.sw/       [R]
RewriteRule ^net.sw/(.*)$ e/netsw/$1

第一条规则纯粹补加URL结尾的「/」号,而第二条规则就是把URL重定向。之后将下列配置存入/e/netsw/.www/.wwwacl

Options      ExecCGI FollowSymLinks Includes MultiViews
 
RewriteEngine on
 
# we are reached via /net.sw/ prefix
RewriteBase  /net.sw/
 
# first we rewrite the root dir to
# the handling cgi scrīpt
RewriteRule  ^$                      netsw-home.cgi    [L]
RewriteRule  ^index\.html$           netsw-home.cgi    [L]
 
# strip out the subdirs when
# the browser requests us from perdir pages
RewriteRule  ^.+/(netsw-[^/]+/.+)$   $1                [L]
 
# and now break the rewriting for local files
RewriteRule  ^netsw-home\.cgi.*      -                 [L]
RewriteRule  ^netsw-changes\.cgi.*   -                 [L]
RewriteRule  ^netsw-search\.cgi.*    -                 [L]
RewriteRule  ^netsw-tree\.cgi$       -                 [L]
RewriteRule  ^netsw-about\.html$     -                 [L]
RewriteRule  ^netsw-img/.*$          -                 [L]
 
# anything else is a subdir which gets handled
# by another cgi scrīpt
RewriteRule  !^netsw-lsdir\.cgi.*    -                 [C]
RewriteRule  (.*)                    netsw-lsdir.cgi/$1

提示:

1.       留意第四部份的L(last)旗标及代表不用更改的('-')符号

2.       留意最后部份第一条规则的! (not)字符,及C (chain)链接符

3.       留意最后一条规则代表全部更新的语法

Apache的mod_imap取代NCSA的imagemap

描述:

很多人都想顺利地把旧的NCSA服务器迁至新的Apache服务器,所以我们都想将旧的NCSAimagemap顺利转换到Apachemod_imap,问题是imagemap已被很多超级链接连系着,但旧的imagemap是存储在/cgi-bin/imagemap/path/to/page.map,而在Apache却是放在/path/to/page.map

方法:

我们只要将「/cgi-bin/」移除便可:

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

在多个目录下搜寻网页

描述:

MultiViews亦不能指示Apache在多个目录里搜寻网页。

方法:

请参看以下指令。

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 scrīptAlias directives,
#  etc.
RewriteRule  ^(.+) - [PT]

跟据URL设定环境变量

描述:

在页面间传递讯息可以用CGI程序完成,但你却不想用CGI而用URL来传递。

方法:

以下指令将变量及其值抽出URL外,然后记入自设的环境变量中,该变量可由XSSICGI存取。例如把/foo/S=java/bar/

TAG: php

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

数据统计

  • 访问量: 45496
  • 日志数: 221
  • 建立时间: 2006-09-27
  • 更新时间: 2008-04-08

RSS订阅

Open Toolbar