apache中的RewriteCond、RewriteRule、rewrite日志

时间:2022-02-27 20:00:06

概述

  Rewirte主要的功能就是实现URL的跳转。可基于服务器级的(httpd.conf)和目录级的(.htaccess) 两种方式。如果要想用到rewrite模块,必须先安装或加载rewrite模块。

去除httpd.conf文件中的
“#LoadModule rewrite_module modules/mod_rewrite.so”
前面的”#”号;

  基于服务器级的(httpd.conf)有两种方法,一种是在httpd.conf的全局下直接利用RewriteEngine on来打开rewrite功能;另一种是在局部里利用RewriteEngine on来打开rewrite功能,下面将会举例说明。
  需要注意的是,必须在每个virtualhost里用RewriteEngine on来打开rewrite功能。否则virtualhost里没有RewriteEngine on它里面的规则也不会生效。
  基于目录级的(.htaccess),要注意一点那就是必须打开此目录的FollowSymLinks属性且在.htaccess里要声明RewriteEngine on。

RewriteCond

  RewriteCond就像我们程序中的if语句一样,表示如果符合某个或某几个条件则执行RewriteCond下面紧邻的RewriteRule语句,这就是RewriteCond最原始、基础的功能,为了方便理解,下面来看看几个例子。

例子一

RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} ^Mozilla/5.0.*
RewriteRule index.php index.m.php

RewriteCond %{HTTP_USER_AGENT} ^Lynx.*
RewriteRule index.php index.L.php

RewriteRule index.php index.b.php

上面语句的作用是当你是用FF浏览器访问index.php这个文件的时候,会自动让你访问到index.m.php这个文件,当你是用一些移动终端访问的 时候,会让你对index.php这个文件的访问实际访问的是index.L.php去,如果你是用其它的浏览器访问的时候,会让你跳到 index.b.php。在说形象一点,上面的语句就等同于程序里面的下面语句(依PHP语句为例):

if($_SERVER['HTTP_USER_AGENT'] == 'Mozilla/5.0')
{
//跳转到对index.m.php的访问
}
else if($_SERVER['HTTP_USER_AGENT'] == 'Lynx')
{
//跳转到对index.L.php的访问
}
else
//跳转到对index.b.php的访问

例子二

RewriteCond %{HTTP_REFERER} (www.test.cn)
RewriteRule (.*)$ test.php

上面语句的作用是如果你访问的url的父页面的主机地址是www.test.cn,则无论你当前访问的是哪个页面,都会跳转到对test.php的访问。

例子三

RewriteCond %{REMOTE_HOST} ^host1.* [OR]
RewriteCond %{REMOTE_HOST} ^host2.* [OR]
RewriteCond %{REMOTE_HOST} ^host3.*
RewriteRule (.*)$ test.php

上面语句的作用是如果你的地址是host1或host2或host3的时候,则就跳到对test.php。从这里可以看出,RewriteCond语句之间默认的是AND,如果想要OR,则要明确的写出来。

说了这么多例子,看看他的语法吧:

RewriteCond TestString CondPattern [flags]

#其中 TestString 为被匹配的字符串,可以是
"RewriteRule反向引用($N)"
"RewriteCond反向引用(%N)"
"服务器变量(%{NAME_OF_VARIABLE})"
"RewriteMap扩展(${mapname:key|default})";

#CondPattern是一个应用于当前实例TestString的正则表达式;
#TestString将会被计算然后与CondPattern匹配.

#返回两个结果,要么为match 要么为no-match,为match继续往下执行。

具体参数参见apache中RewriteCond中文手册

RewriteRule

此指令可以多次使用。每个指令定义一个简单的重写规则。这些规则的定义顺序尤为重要――在运行时,规则是按这个顺序逐一生效的。
语法如下:

RewriteRule Pattern Substitution [flags]

# Pattern是一个作用于当前URL的perl兼容的正则表达式。
#"当前URL"是指该规则生效时刻的URL的值。
#它可能与被请求的URL截然不同,
#因为其他规则可能在此之前已经发生匹配并对它做了改动。

# Substitution是当原始URL与Pattern相匹配时,
#用来替代(或替换)的字符串。

# [flags] 详细见下面的参考链接

具体参数参见
Apache ReWriteRule参数
apache中RewriteCond中文手册
给一张[flag]速查表
apache中的RewriteCond、RewriteRule、rewrite日志

最典型的例子

<IfModule mod_rewrite.c>
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.*)$ index.php?url=$1 [PT,L]

</IfModule>

上面规则,意思是当前请求不是文件,也不是目录,这将url重写到index.php入口文件。

调试Apache的rewrite规则方法(rewrite日志)

你调试apache的重写规则调试到抓狂过吗?
你有看到项目htaccess中N条重写规则而不知所措吗?
我想肯定有,下面介绍让如何让你明明白白的调试apache的重写规则。

1. apache版本在2.4以下

mod_rewrite是带有日志功能的,开启的方法如下:
在apache的配置文件中增加

RewriteLog "/myfolder/mylogfile.log" 
RewriteLogLevel 9

Rewriteloglevel 0 代表关闭,9代表开启最大debug输出,调为9可以看到最详细的重写匹配信息.请将上面”/myfolder/mylogfile.log”替换为你电脑上的实际路径,添加好之后重启apache,访问重写页面的时候apache就会自动的日志文件里面增加记录了。

2. apache版本2.4及以上

那些熟悉早期版本的mod_rewrite的无疑将寻找RewriteLog和RewriteLogLevel指令。此功能已被下述的新的模块的日志记录配置完全取代。

LogLevel alert rewrite:trace3

其中,记录等于由trace1~trace8,数值越大,记录的信息越多。你将能够在你的 apache配置的error_log 中看到这些信息。

注意:

  • Apache的RewriteLog指令只能在conf文件中,不能在.htaccess文件。
  • 使用高跟踪日志级别的mod_rewrite将显着减慢你的Apache HTTP服务器!使用日志级别高于trace2只用于调试!
  • 生产环境请连配置项目都移除,以免影响性能。