Apache Rewrite 参数 重定向问题汇总

kevin.Zhu 发布于:2013-2-17 16:32 分类:Apache  有 23 人浏览,获得评论 0 条  

apache 的 rewrite模块 用了也有段时间了。每次都是先从历史中找资料修改。今天腾出点时间整理下和大家分享一下,其实rewrite规则超多,我也没有全部理解,实践中我用的一些列出来,相信一般应用的朋友足够了

 

 

为什么需要用重写规则?


他人总结:

一个网站,如果是长期需要放在internet上提供服务,必定会有不断地更新和维护,如临 时转移到其它服务器进行维护,重新组织目录结构,变换URL甚至改变到新的域名等等, 而为了让客户不会因此受到任何影响,最好的方法就是使用Apache Rewrite Rule(重写
规则)。

  • 当在浏览器的地址栏输入一个无效的参数时,会出现数据库的错误提示,这是一个安全的隐患

  • 搜索引擎无法收录你的所有网页

  • 网页的链接地址是一系列的参数,对浏览用户和搜索引擎都不易理解

  •  

    我的总结:

    rewrite可以保持接口的固定稳定性,防止图片盗链,增加搜索引擎的爬去机会,同事还能给人深不可测的感觉(猜不透你用的后端是什么技术和语言写的) 

    常见的Dz论坛就喜欢这样干,优化了搜索引擎,有看上去静态话给人一种高深的感觉:

      RewriteRule ^(.*)/archiver/((fid|tid)-[/w/-]+/.html)$ $1/archiver/index.php?$2
      RewriteRule ^(.*)/forum-([0-9]+)-([0-9]+)/.html$ $1/forumdisplay.php?fid=$2&page=$3

     

     

    配置

    我这里用的是apache2的模块,IIS中也可以配置,相信原理基本类似。

    在httpd.conf里定义LoadModule rewrite_module modules/mod_rewrite.so

    虚拟主机配置中定义 具体的rewrite规则。 

    这里相信大家都熟悉,我就不说了


     

     

    Apache的RewriteRule规则详细介绍:

    R[=code](force redirect) 强制外部重定向

    F(force URL to be forbidden)禁用URL,返回403HTTP状态码。

    G(force URL to be gone) 强制URL为GONE,返回410HTTP状态码。

    P(force proxy) 强制使用代理转发。 )

    L(last rule) 表明当前规则是最后一条规则,停止分析以后规则的重写。
    N(next round) 重新从第一条规则开始运行重写过程。
    C(chained with next rule) 与下一条规则关联
    如果规则匹配则正常处理,该标志无效,如果不匹配,那么下面所有关联的规则都跳过。

    T=MIME-type(force MIME type) 强制MIME类型
    NS (used only if no internal sub-request) 只用于不是内部子请求

    NC(no case) 不区分大小写
    QSA(query string append) 追加请求字符串

    NE(no URI escaping of output) 不在输出转义特殊字符

    例如:RewriteRule /foo/(.*) /bar?arg=P1/%3d$1 [R,NE] 将能正确的将/foo/zoo转换成/bar?arg=P1=zed +3a?` Z
    PT(pass through to next handler) 传递给下一个处理

    例如: :5/Uh/ sX
    RewriteRule ^/abc(.*) /def$1 [PT] # 将会交给/def规则处理

    S=num(skip next rule(s)) 跳过num条规则

    E=VAR:VAL(set environment variable) 设置环境变量

     

    我们从实战中获得些实用的实例:

     

    简单的虚拟主机配置:

    <VirtualHost *:80>
         DocumentRoot E:/JAVA_WorkSpace/bsei_mapenjoy_passport_tomcat/WebRoot
         ServerName www.boshilian.com
         ErrorDocument 404   /index.html
         <IfModule mod_rewrite.c>
         RewriteEngine On
         RewriteRule /22.htm(.+)$ /help.jsp?$1 [L]
         RewriteRule /33.htm(.+)$ /help.jsp?$1 [R]
         RewriteRule /44.htm(.+)$ http://www.sohu.com?$1 [L]
         RewriteRule /55.htm(.+)$ http://www.sohu.com?$1 [R] 

         RewriteRule /66.htm(.+)$ http://www.sohu.com?$1 [P] 

         RewriteCond %{QUERY_STRING} ^t/=(.+)?$ [NC]
         RewriteRule ^/api$ http://www.sina.com.cn?t=%1 [P]

    </IfModule>
    </VirtualHost>

     

    最简单的重定向:

     

    下面列一下常用简单的,相信大家都熟悉,我就简单列一下:

     

    url不发生变化,直接定向,类似于java中的forword:

    RewriteRule /22.htm(.+)$ /help.jsp?$1 [L]

     

    url发生变化,直接定向,redirect转向,(支持跨域):
    RewriteRule /33.htm(.+)$ /help.jsp?$1 [R]

    RewriteRule /44.htm(.+)$ http://www.sohu.com?$1 [L]
    RewriteRule /55.htm(.+)$ http://www.sohu.com?$1 [R]

     

     

    问题汇总(关键在这)

    一般遇到2类问题居多,下面做解决的陈述:

    url不变,内容变化的重定向


     

    apache+tomcat Rewrite遇到的问题,又跨域,又要url不变的重定向

    这里我遇到了一个问题,就是我用apache + tomcat配置整合的时候, apche对于tomcat的重定向目录解析不正确,rewrite始终认为哪个目录为apache下的。如果用跨域的跳转(全域名的),url就会发生变化。这样不太爽。

    我们可以用以下方法解决:(这样浏览器中的url还是66.htm , 但是内容已经是sina的了)

    RewriteRule /66.htm$  http://www.sina.com.cn [P]

    RewriteRule /66.htm$  http://127.0.0.1:8080/sohu/sd.jsp [P]

    注意:这里的P是代理模式转发,必须用url全称,并且要保证modProxy打开,也就是下面httpd.conf中的着两句:

    LoadModule proxy_module modules/mod_proxy.so
    LoadModule proxy_http_module modules/mod_proxy_http.so

    如果不打开则会出现403禁止页面。

     

    rewrite重定向中的?问号参数问题

     

    rewrite前面的参数的?是不能发送的,需要处理一下

     

    http://www.boshilian.com/api?t=2323&v=23232&nond=323we

     

    rewrite为:

    http://www.sina.com.cn?t=2323&v=23232&nod=323we

     

    配置写法如下:(url不变)

    RewriteCond %{QUERY_STRING} ^t/=(.+)?$ [NC]
    RewriteRule ^/api$ http://www.sina.com.cn?t=%1 [P]

     

    或者(url变化)

    RewriteCond %{QUERY_STRING} ^t/=(.+)?$ [NC]
    RewriteRule ^/api$ http://www.sina.com.cn?t=%1 [L]

     

    这样就可以把?后面的 t 参数转发过去。

     

    官方文档解释为:
    注意:查询字符串
    Pattern 不会按照查询字符串进行匹配。为了达到这个目的,你必须使用一个带有 %{QUERY_STRING} 变量的 RewriteCond 指令。

    当 然,你也可以在替换字符串中创建包含查询字符串的 url:在替换字符串中使用问号,以标明其后的部分应该被重新注入到QUERY_STRING中。

    而要删除一个已有的请求串,则可以用问号来终结替换字符串。为了联合新旧查询字符串,请使用[QSA]标志。

     

     

    先写这么多,rewrite还有很多参数组合的应用,我这里先不介绍,应用深入这可以一起留言讨论。