前阵子某天,一同事让我帮忙看一下某内部服务器的域名跳转的配置,原本这两年好像没作Web服务器方面东西了,不过鉴于曾经在互联网行业工做过,仍是略懂Apache配置,也想顺便玩一下。最后的配置仍是比价简单的,也实现了他所需的功能。今天有点空闲时间,想写篇博客总结一些apache rewrite的配置语法和实例(源于网络资料),以便从此快速查阅。php
我最后其实就在httpd.conf文件写了以下几行配置就将域名中以“otc-team”开头的URL重定向为“http://otcteam.mycompany.com/”下面的对应URL。css
1html 2web 3正则表达式 |
RewriteEngine onexpress RewriteCond %{HTTP_HOST} ^otc-team [NC]apache RewriteRule ^(.*) http://otcteam.mycompany.com/$1 [L]api |
1. 一些基础知识的介绍:
The mod_rewrite module uses a rule-based rewriting engine, based on a PCRE regular-expression parser, to rewrite requested URLs on the fly. By default, mod_rewrite maps a URL to a filesystem path. However, it can also be used to redirect one URL to another URL, or to invoke an internal proxy fetch.
mod_rewrite provides a flexible and powerful way to manipulate URLs using an unlimited number of rules. Each rule can have an unlimited number of attached rule conditions, to allow you to rewrite URL based on server variables, environment variables, HTTP headers, or time stamps.
mod_rewrite operates on the full URL path, including the path-info section. A rewrite rule can be invoked in httpd.conf or in .htaccess. The path generated by a rewrite rule can include a query string, or can lead to internal sub-processing, external request redirection, or internal proxy throughput.
简单解释一下内部重定向和外部重定向吧。内部重定向,是指域名并不发生变化,只是将某个URL映射到了文件系统中的另外一个路径。外部重定向,是指URL已经法发生变化(在浏览器中显示看到的域名也跟着变化了),从一个URL映射到了另外一个URL(能够是不一样主机的,固然也能够是同一主机上的)。
PCRE(Perl Compatible Regular Expressions)是与Perl5.x兼容的正则表达式,使用这种正则表达式的著名软件项目有Apache、PHP、KDE、Safari等。浏览器
重写规则的做用范围,有以下三种:
1) 可使用在Apache主配置文件httpd.conf中
2) 可使用在httpd.conf里定义的虚拟主机配置中
3) 可使用在基本目录的跨越配置文件.htaccess中
首先,apache在编译时将mod_rewrite编译为模块,而后在Apache的配置文件中加载它:
LoadModule rewrite_module modules/mod_rewrite.so
其次,这三种方式,都须要在写规则前,用“RewriteEngine on”指令来打开rewrite功能。
假如你对你的的网站内容所在的服务器没有管理员权限,或者你的网站放在ISP的服务器上托管等等条件下,你没法改写主配置文件,然而你能够对你的WEB站点内容所在的目录有写权限,则你能够设置本身的.htaccess文件。 (本博客站点就有设置.htaccess文件作rewrite。)对文件.htaccess所做的任何改动不须要重启动Apache. 不过,值得注意的是,须要肯定主配置文件中对你的网站所在的目录定义了下面的内容:
Options Indexes FollowSymLinks
AllowOverride all
不然你的.htaccess文件配置不会工做。
2. Apache mod_rewrite规则重写的标志一览服务器
1) R[=code](force redirect) 强制外部重定向
强制在替代字符串加上http://thishost[:thisport]/前缀重定向到外部的URL.若是code不指定,将用缺省的302 HTTP状态码。
2) F(force URL to be forbidden)禁用URL,返回403HTTP状态码。
3) G(force URL to be gone) 强制URL为GONE,返回410HTTP状态码。
4) P(force proxy) 强制使用代理转发。
5) L(last rule) 代表当前规则是最后一条规则,中止分析之后规则的重写。
6) N(next round) 从新从第一条规则开始运行重写过程。
7) C(chained with next rule) 与下一条规则关联
若是规则匹配则正常处理,该标志无效,若是不匹配,那么下面全部关联的规则都跳过。
8.) T=MIME-type(force MIME type) 强制MIME类型
9) NS (used only if no internal sub-request) 只用于不是内部子请求
10) NC(no case) 不区分大小写
11) QSA(query string append) 追加请求字符串
12) NE(no URI escaping of output) 不在输出转义特殊字符
例如:RewriteRule /foo/(.*) /bar?arg=P1%3d$1 [R,NE] #将能正确的将/foo/zoo转换成/bar?arg=P1=zoo
13) PT(pass through to next handler) 传递给下一个处理
例如:
RewriteRule ^/abc(.*) /def$1 [PT] # 将会交给/def规则处理
Alias /def /ghi
14) S=num(skip next rule(s)) 跳过num条规则
15) E=VAR:VAL(set environment variable) 设置环境变量
另外,P是代理模式转发,必须用url全称,而且要保证modProxy打开,也就是下面httpd.conf中的以下两个指令:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
若是对应proxy模块没加载,则会出现403禁止页面。
3. 一些有用的实际rewrite例子
例1.下面是在一个虚拟主机里定义的规则。功能是把client请求的主机前缀不是www.smilejay.com和173.192.169.119都跳转到主机前缀为http://www.smilejay.com,避免相同内容的网页有多个指向的域名,如http://smilejay.com
1 2 3 4 5 6 7 8 9 10 |
NameVirtualHost 173.192.169.119:80 ServerAdmin smile665(AT)gmail.com DocumentRoot "/web" ServerName smilejay.com
RewriteEngine on #打开rewirte功能 RewriteCond %{HTTP_HOST} !^www.smilejay.com [NC] #声明Client请求的主机中前缀不是www.smilejay.com,其中 [NC] 的意思是忽略大小写 RewriteCond %{HTTP_HOST} !^173.192.169.119 [NC] #声明Client请求的主机中前缀不是70.40.213.183,其中 [NC] 的意思是忽略大小写 RewriteCond %{HTTP_HOST} !^$ #声明Client请求的主机中前缀不为空 RewriteRule ^(.*) http://www.smilejay.com/ [L] #含义是若是Client请求的主机中的前缀符合上述条件,则直接进行跳转到http://www.smilejay.com/,[L]意味着当即中止重写操做,并再也不应用其余重写规则。这里的.*是指匹配全部URL中的任意字符,()括号的功能是把全部的字符作一个标记,以便于后面用$1这样的变量来引用,就是引用前面里的(.*)字符。 |
例2. 将输入 en.smilejay.com 的域名时跳转到www.smilejay.com
1 2 3 |
RewriteEngine on RewriteCond %{HTTP_HOST} ^en.smilejay.com [NC] RewriteRule ^(.*) http://www.smilejay.com/ [L] |
例3. 赛卡软件近期更换了域名,新域名为www.sicasoft.com, 更加简短好记。这时须要将原来的域名ss.kiya.cn, 以及论坛所在地址ss.kiya.cn/bbs/定向到新的域名,以便用户能够找到,而且使原来的论坛 URL 继续有效而不出现 404 未找到,好比原来的http://ss.kiya.cn/bbs/tread-60.html, 让它在新的域名下继续有效,点击后转发到http://bbs.sicasoft.com/tread-60.html,而其余网页,如原先的http://ss.kiya.cn/purchase不会到二级域名bbs.sicasoft.com/purchase上,而是到www.sicasoft.com/purchase
按照这样的要求重定向规则应该这样写:
1 2 3 4 5 |
RewriteEngine On RewriteCond %{REQUEST_URI} ^/bbs/ RewriteRule ^bbs/(.*) http://bbs.sicasoft.com/$1 [R=permanent,L] RewriteCond %{REQUEST_URI} !^/bbs/ RewriteRule ^(.*) http://www.sicasoft.com/$1 [R=permanent,L] |
例4: 同时达到下面两个要求:
1.用http://www.zzz.com/xxx.php 来访问 http://www.zzz.com/xxx/
2.用http://yyy.zzz.com 来访问 http://www.zzz.com/user.php?username=yyy 的功能
1 2 3 4 5 6 7 8 |
RewriteEngine On RewriteCond %{HTTP_HOST} ^www.zzz.com RewriteCond %{REQUEST_URI} !^user.php$ RewriteCond %{REQUEST_URI} .php$ RewriteRule (.*).php$ http://www.zzz.com/$1/ [R] RewriteCond %{HTTP_HOST} !^www.zzz.com RewriteRule ^(.+) %{HTTP_HOST} [C] RewriteRule ^([^.]+).zzz.com http://www.zzz.com/user.php?username=$1 |
例5:实现以下URL的rewrite:
/type*.html 被重定向为 /type.php?typeid=*
/type*page*.html 被重定向为 /type.php?typeid=*&page=*
1 2 |
RewriteRule ^/type([0-9]+).html$ /type.php?typeid=$1 [PT] RewriteRule ^/type([0-9]+)page([0-9]+).html$ /type.php?typeid=$1&page=$2 [PT] |
例6.使用Apache的URL Rewrite配置多用户虚拟服务器
要实现这个功能,首先要在DNS服务器上打开域名的泛域名解析(本身作或者找域名服务商作)。好比,我就把 *.kiya.us和 *.kiya.cn所有解析到了个人IP地址70.40.213.183上。而后,看一下个人Apache中关于*.kiya.us的虚拟主机的设定。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
ServerAdmin webmaster@kiya.us DocumentRoot /home/www/www.kiya.us ServerName dns.kiya.us ServerAlias dns.kiya.us kiya.us *.kiya.us CustomLog /var/log/httpd/osa/access_log.log” common ErrorLog /var/log/httpd/osa/error_log.log” AllowOverride None Order deny,allow
RewriteEngine on RewriteCond %{HTTP_HOST} ^[^.]+.kiya.(cn|us)$ RewriteRule ^(.+) %{HTTP_HOST}$1 [C] RewriteRule ^([^.]+).kiya.(cn|us)(.*)$ /home/www/www.kiya.us/sylvan$3?un=$1&%{QUERY_STRING} [L] |
在这段设定中,我把*.kiya.cn和*.kiya.us 的Document Root都设定到了 /home/www/www.kiya.us
继续看下去,在这里我就配置了URL Rewrite规则。
RewriteEngine on #打开URL Rewrite功能
RewriteCond %{HTTP_HOST} ^[^.]+.kiya.(cn|us)$ #匹配条件,若是用户输入的URL中主机名是相似 xxxx.kiya.us 或者 xxxx.kiya.cn 就执行下面一句
RewriteRule ^(.+) %{HTTP_HOST}$1 [C] #把用户输入完整的地址(GET方式的参数除外)做为参数传给下一个规则,[C]是Chain串联下一个规则的意思
RewriteRule ^([^.]+).kiya.(cn|us)(.*)$ /home/www/dev.kiya.us/sylvan$3?un=$1&%{QUERY_STRING} [L]
# 最关键的是这一句,使用证则表达式解析用户输入的URL地址,把主机名中的用户名信息做为名为un的参数传给/home/www/dev.kiya.us目录下的脚本,并在后面跟上用户输入的GET方式的传入参数。并指明这是最后一条规则([L]规则)。注意,在这一句中指明的重写后的地址用的是服务器上的绝对路径,这是内部跳转。若是使用http://xxxx这样的URL格式,则被称为外部跳转。使用外部跳转的话,浏览着的浏览器中的URL地址会改变成新的地址,而使用内部跳转则浏览器中的地址不发生改变,看上去更像实际的二级域名虚拟服务器。
设置后重启Apache服务器就大功告成了! (从新让apache从新reload配置便可)
例6. 经过Rewrite防止盗链 (常常看到有的网站对图片盗链有限制,其实设置就是这么简单)
不容许www.im286.com www.chinaz.com 这两个网站盗链 , 其它的网站均可以盗链的规则怎么写.
1 2 3 4 |
RewriteEngine On RewriteCond %{HTTP_REFERER} chinaz.com [NC] RewriteCond %{HTTP_REFERER} im286.com [NC] RewriteRule .*\.(jpg|jpeg|gif|png|rar|zip|txt|ace|torrent|gz|swf)$ http://www.xxx.com/fuck.png [R,NC,L] |
例7. 关因而否须要使用彻底转义,好比在 RewriteCond %{HTTP_REFERER} chinaz.com [NC] 中 把 chinaz.com 改为 chinaz\.com
答案是,二者都是能够的。
例8. 另外几个小例子:
1. 屏蔽IE和Opera浏览器(User-Agent)
1 2 3 4 |
RewriteEngine on RewriteCond %{HTTP_USER_AGENT} ^MSIE [NC,OR] RewriteCond %{HTTP_USER_AGENT} ^Opera [NC] RewriteRule ^.* – [F,L] #这里"-"表示没有替换,浏览器为IE和Opera的访客将被禁止访问。 |
2. 自动添加.php扩展名及自动换.html到.php扩展名
1 2 3 4 5 6 7 |
RewriteEngine On RewriteBase /test RewriteCond %{REQUEST_FILENAME}.php -f RewriteRule ([^/]+)$ /test/$1.php #for example: /test/admin => /test/admin.php RewriteRule ([^/]+)\.html$ /test/$1.php [L] #for example: /test/admin.html => /test/admin.php |
3. 限制仅显示图片,而不能显示其余文件的请求。
1 2 3 4 5 6 |
#限制目录只能显示图片 < IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{REQUEST_FILENAME} !^.*\.(gif|jpg|jpeg|png|swf)$ RewriteRule .*$ – [F,L] < /IfModule> |
补充,关于特定文件扩展名的重写。
重写有某些扩展名的文件:
RewriteRule (.*.css$|.*.js$) gzip.php?$1 [L]
若是要排除一些扩展名:
RewriteRule !\.(js|ico|gif|jpg|JPG|png|PNG|css|pdf|swf)$ index.php
参考资料: 摘录资料的博客1:http://slj.me/2009/04/apache-rewrite-regular/ 摘录资料的博客2:http://blog.csdn.net/chaiqi/article/details/5620427 apache rewrite官网手册:http://httpd.apache.org/docs/current/mod/mod_rewrite.html PCRE介绍:http://www.pcre.org/