文章随机晒最新文章关照最多的

jiayi Rss

Apache Rewrite笔记及示例

| Posted in Apache |

17

更换了新的域名:jiayii.com,于是想把jiayii.cn重定向到相应的jiayii.com上。此时此刻想到了apache的Rewrite,虽然知道大概的规则,但亲自动手从未成功过。。这次横下心,不断尝试,终于大功告成。现把自己的规则与书写心得记录下来,同时贴下Rewrite中非常重要的[flags]参数的解释。

我的书写规则如下

  1. RewriteCond %{HTTP_HOST} ^www.jiayii.cn$
  2. RewriteCond %{HTTP_HOST} !^$
  3. RewriteCond %{HTTP_HOST} !^feed&
  4. RewriteCond %{REQUEST_URI} !^/feed
  5. RewriteRule (.*)$ /$1 [R=permanent]
  6.  
  7. RewriteCond %{REQUEST_URI} .php.*$
  8. RewriteRule (.*).php/?[^/]*/?(.*)$ $1/$2 [R=permanent,L]
  9.  

其中
RewriteRule
(.*)$ /$1 [R=permanent] 将http://www.jiayii.cn/artice重定向到http://www.jiayii.com/artice.php
RewriteRule (.*)/.php$ $1 [R=permanent,L] 将URL任何位置的.php去掉。
点击本文的jiayii.cn连接http://www.jiayii.cn/showart/apache-rewrite-record-and-examples-16查看效果

以下介绍两个RewriteRule的基本知识

RewriteRule
Syntax: RewriteRule Pattern Substitution [flags]


回想前几次的失败,主要原因是对RrwriteRule中的pattern理解模糊,这次仔细看了手册,pattern指的是

a perl compatible regular expression which gets applied to the current URL. Here "current" means the value of the URL when this rule gets applied. This may not be the originally requested URL, because any number of rules may already have matched and made alterations to it.

理解了pattern,之后的[flags]选项也至关重要

  1. ‘forbidden|F’ (强制禁止访问URL所指的资源)
    立即返回状态值403 (FORBIDDEN)的应答包。将这个标志与合适的RewriteConds 联合使用,可以阻断访问某些URL。
  2. ‘gone|G’ (强制返回URL所指资源为不存在(gone))
    立即返回状态值410 (GONE)的应答包。用这个标志来标记URL所指的资源永久消失了.
  3. ‘proxy|P’ (强制将当前URL送往代理模块(proxy module))
    这个标志,强制将substitution当作一个发向代理模块的请求,并立即将共送往代理模块。因此,必须确保substitution串是一个合 法的URI (如, 典型的情况是以http://hostname开头),否则会从代理模块得到一个错误. 这个标志,是ProxyPass指令的一个更强劲的实现,将远程请求(remote stuff)映射到本地服务器的名字空间(namespace)中来。
    注意,使用这个功能必须确保代理模块已经编译到Apache 服务器程序中了. 可以用“httpd -l ”命令,来检查输出中是否含有mod_proxy.c来确认一下。如果没有,而又需要使用这个功能,则需要重新编译“httpd”程序并使用 mod_proxy有效。
  4. ‘last|L’ (最后一条规则)
    中止重写流程,不再对当前URL施加更多的重写规则。这相当于perl的last命令或C的break命令。
  5. ‘next|N’ (下一轮)
    重新从第一条重写规则开始执行重写过程,新开的过程中的URL不应当与最初的URL相同。 这相当于Perl的next命令或C的continue命令. 千万小心不要产生死循环。
  6. ‘chain|C’ (将当前的规则与其后续规则綑绑(chained))
    当规则匹配时,处理过程与没有綑绑一样;如果规则不匹配,则綑绑在一起的后续规则也不在检查和执行。
  7. ‘type|T=MIME-type’ (强制MIME类型)
    强制将目标文件的MIME-type为某MIME类型。例如,这可用来模仿mod_alias模块对某目录的ScriptAlias指定,通过强制将该目录下的所有文件的类型改为 “application/x-httpd-cgi”.
  8. ‘nosubreq|NS’ (used only if no internal sub-request )
    这个标志强制重写引擎跳过为内部sub-request的重写规则.例如,当mod_include试图找到某一目录下的默认文件时 (index.xxx),sub-requests 会在Apache内部发生. Sub-requests并非总是有用的,在某些情况下如果整个规则集施加到它上面,会产生错误。利用这个标志可排除执行一些规则。
  9. ‘nocase|NC’ (模板不区分大小写)
    这个标志会使得模板匹配当前URL时忽略大小写的差别。
  10. ‘qsappend|QSA’ (追加请求串(query string))
    这个标志,强制重写引擎为Substitution的请求串追加一部分串,则不是替换掉原来的。借助这个标志,可以使用一个重写规则给请求串增加更多的数据。
  11. ‘noescape|NE’ (不对输出结果中的特殊字符进行转义处理)
    通常情况下,mod_write的输出结果中,特殊字符(如’%’, ‘$’, ‘;’, 等)会转义为它们的16进制形式(如分别为’%25′, ‘%24’, and ‘%3B’)。这个标志会禁止mod_rewrite对输出结果进行此类操作。 这个标志只能在 Apache 1.3.20及以后的版本中使用。
  12. ‘passthrough|PT’ (通过下一个处理器)
    这个标志强制重写引擎用filename字段的值来替换内部request_rec数据结构中uri字段的值。. 使用这个标志,可以使后续的其它URI-to-filename转换器的Alias、ScriptAlias、Redirect等指令,也能正常处理 RewriteRule指令的输出结果。用一个小例子来说明它的语义:如果要用mod_rewrite的重写引擎将/abc转换为/def,然后用 mod_alas将/def重写为ghi,则要:
    RewriteRule ^/abc(.*) /def$1 [PT]
    Alias /def /ghi
    如果PT标志被忽略,则mod_rewrite也能很好完成工作,如果., 将 uri=/abc/… 转换为filename=/def/… ,完全符合一个URI-to-filename转换器的动作。接下来 mod_alias 试图做 URI-to-filename 转换时就会出问题。
    注意:如果要混合都含有URL-to-filename转换器的不同的模块的指令,必须用这个标志。最典型的例子是mod_alias和mod_rewrite的使用。
  13. ‘skip|S=num’ (跳过后面的num个规则)
    当前规则匹配时,强制重写引擎跳过后续的num个规则。用这个可以来模仿if-then-else结构:then子句的最后一条rule的标志是skip=N,而N是else子句的规则条数。
  14. ‘env|E=VAR:VAL’ (设置环境变量)
    设置名为VAR的环境变量的值为VAL,其中VAL中可以含有正则式的后向引用($N或%N)。这个标志可以使用多次,以设置多个环境变量。这儿设置 的变量,可以在多种情况下被引用,如在XSSI或CGI中。另外,也可以在RewriteCond模板中以%{ENV:VAR}的形式被引用。

留两个Rewrite的例子:

例一:下面是在一个虚拟主机里定义的规则。功能是把client请求的主机前缀不是www.colorme.com和203.81.23.202都跳转
到主机前缀为http://www.colorme.com.cn,避免当用户在地址栏写入http://colorme.com.cn时不能以会员方式
登录网站。  
RewriteCond %{HTTP_HOST} !^www.colorme.com.cn [NC] #声明Client请求的主机中前缀不是www.colorme.com.cn,[NC]的意思
是忽略大小写 
RewriteCond %{HTTP_HOST} !^203.81.23.202 [NC] #声明Client请求的主机中前缀不是203.81.23.202,[NC]的意思是忽略大小写 
RewriteCond %{HTTP_HOST} !^$ #声明Client请求的主机中前缀不为空,[NC]的意思是忽略大小写 
RewriteRule ^/(.*) http://www.colorme.com.cn/ [L]
#含义是如果Client请求的主机中的前缀符合上述条件,则直接进行跳转到http://www.colorme.com.cn/,
[L]意味着立即停止重写操作,并不再应用其他重写规则。这里的.*是指匹配所有URL中不包含换行字符,()括号的功能是把所有的
字符做一个标记,以便
于后面的应用.就是引用前面里的(.*)字符。

例二:将输入 folio.test.com 的域名时跳转到profile.test.com 
listen 8080
NameVirtualHost 10.122.89.106:8080 
ServerAdmin webmaster@colorme.com.cn
DocumentRoot "/usr/local/www/apache22/data1/"
ServerName profile.test.com
RewriteEngine on 
RewriteCond %{HTTP_HOST} ^folio.test.com [NC]
RewriteRule ^/(.*) http://profile.test.com/ [L] 

具体Rewrite规则参见相关手册http://man.chinaunix.net/newsoft/ApacheMenual_CN_2.2new/mod/mod_rewrite.html
推荐一篇不错的文章http://hi.baidu.com/tb12345/blog/item/ecd2091f95466bcca6866949.html

Comments (17)

你好,想请教帮忙下咯
如果我想把域名http://xmlinuxers.cn重定向到新的域名http://qingxianyan.cn上 apache_rewrite 该如何实现哦 因为之前都没有使用过这功能 能否实现访问xmlinuxers.cn里的文章直接重定向到qingxianyan.cn新域名上咯 还有就是新域名qingxianyan.cn上的博客是不是也要有与旧博客xmlinuxers.cn同样的文章或标题哦?!

好久没用Rewrite了,而且不知道你的URL具体重写规则,你试试这个,能重定向过去,URL估计也不美观……
RewriteCond %{HTTP_HOST} ^xmlinuxers\.cn$
RewriteCond %{HTTP_HOST} !^$
RewriteRule (.*)$ http://qingxianyan.cn/$1 [R=permanent]

文章标题最好一致

嗯 好滴 我再试试看 因为最近事情太多 估计没啥时间折腾 非常谢谢你咯 =_=///
ps:发觉北邮人都挺友好 嗯

@Yousri
冒昧问一句,你怎么知道俺是北邮人……

难道我记错了?!混淆了啊?! 额 如果记错了表示抱歉

@Yousri
木有,确实是byr…嘿

因为我沉浸在你们byr的BBS论坛上/// 是从那知道这里的

Write a comment

You must be logged in to post a comment.