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类问题居多,下面做解决的陈述:
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还有很多参数组合的应用,我这里先不介绍,应用深入这可以一起留言讨论。