Apache地址重写的几个问题
Apache地址重写的配置分为两种方式,即通过httpd.conf配置和.htaccess文件。
首先要打开rewrite模块,windows下的配置是
LoadModule rewrite_module modules/mod_rewrite.so
httpd.conf的配置可以全局生效,也可以只配置一个目录,需要做的事情是在相应目录的Directory标签下配置Rewrite规则。
.htaccess的则放到相应目录下(或者根目录)即可,这是VPS里常用的一种方式,毕竟作为一个VPS购买者不可能要求提供商去更改全局配置文件。这种方式需要注意的有如下两点:
首先,.htaccess要想起作用,必须要在httpd.conf中相应的Directory标签下配置AllowOverride All(默认是None),其次是windows下这种无文件名仅有扩展名的文件是无法直接生成的,可以在cmd窗口下使用copy con命令来生成(这命令也有年头了,我小学的时候还学过,光阴荏苒啊,扯远了…),Ctrl+Z<Enter>保存。
然后我们说一下几个概念。
首先是RewriteEngine,这是地址重写的引擎,可以方便的设置为On或者Off来启用和关闭引擎。
其次是RewriteCond,地址重写的条件,符合这个条件的才进行表达式判断和重写,这样能有效减少匹配的条数,提高重写效率。
最后是RewriteBase和RewriteRule,RewriteBase指明重定向地址的基础,即RewriteRule后一部分重定向地址会拼合上RewriteBase,合成一个完整的重定向地址。这在一个web容器下有多个网站的时候比较有用。
RewriteRule才是我们讨论的主要话题。RewriteRule实现把符合表达式的地址重定向到另一个地址的功能,RewriteRule的语法类似于下面
RewriteRule ^forum-([0-9]+)-([0-9]+)\.html$ forumdisplay.php?fid=$1&page=$2
RewriteRule紧跟着判断表达式,之后是需要重定向的位置,正则表达式()会捕获一个分组,然后通过$n引用这个分组,从而实现地址重写。RewriteRule匹配的开始位置是整个URL去掉当前目录后剩下的部分,比如我在/discuz配置上面所示的RewriteRule,然后输入一个URL-http://localhost/discuz/forum-1-1.html,被用来匹配的输入会是forum-1-1.html,也就是前面的/discuz/被吃掉了。对于整个问题,我们可以用如下的语句验证。
RewriteRule ^(.*)/forum-([0-9]+)-([0-9]+)\.html$ rewrite.php?param=$1
注:在rewrite.php里打印一下GET['param’]参数
另外这里需要说明的是,如果我定义了
RewriteBase /discuz
那么前面的^forum-([0-9]+)-([0-9]+)\.html$不受影响,但是后面会变成/discuz/forumdisplay.php?fid=$1&page=$2。不过RewriteBase并不是必须的,若有指定RewriteBase,结果为RewriteBase+重定向地址,否则为当前目录+重定向地址。这里当前目录指的是.htaccess所在目录(使用.htaccess的时候)或者Directory标签指定的目录(使用httpd.conf的时候)。
以上操作在windows下测试通过。
参考文献:
[1]Apache中RewriteCond规则参数介绍,
http://hi.baidu.com/%D2%BB%CE%C4%CC%EC/blog/item/ace7f14e19851cc4d0c86af2.html
[2]RewriteRule-htaccess详细语法使用教程,
http://www.3code.cn/rewriterule-htaccess%E8%AF%A6%E7%BB%86%E8%AF%AD%E6%B3%95%E4%BD%BF%E7