Discuz!官方免费开源建站系统

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

与SS有关的rewrite快速入门教程

[复制链接]
littlehz 发表于 2009-7-24 17:22:40 | 显示全部楼层 |阅读模式
本帖最后由 littlehz 于 2009-7-31 10:43 编辑

近期看到论坛上很多网友需要写rewrite,除了默认的rewrite规则,有时想要实现自己的一些跳转,这就需要自写rewrite了,本教程为快速入门教程,目标是阅读本教程30分钟内对rewrite有所了解能自写简单的rewrite规则,本人较了解Linux的Nginx平台,出于通用性考虑将rewrite写成Apache适用的,如果需要IIS的rewrite请参照自行修改,本人不深入了解IIS只略只其一二。

楼层导读:
1#:rewrite基本概念
2#:ss默认规则解读以及自写rewrite一般流程
3#:常见问题解答

思考:为什么要伪静态?正常情况下,我的域名www.littz.cn是指向64.71.167.26这个IP地址的服务器,服务器上配置了www.littz.cn的域名是对应 /aaa/www这个目录,假设我们输入一个http://www.littz.cn/viewnews-340.html,那么服务器会找/aaa/www目录下有没有viewnews-340.html文件的。但是用SS的朋友你们看看服务器对应目录下有没有这个文件?没有吧,但是为什么这个URL又能访问呢,是因为rewrite伪静态,服务器的WEB软件(我用的是Nginx,Apache、IIS也是属于这种软件)依据写的rewrite规则在服务器做了内部处理,实际上是请求index.php,并传递参数action-viewnews-itemid-340.html给index.php了。

rewrite其实就是跳转,跳转有三种,内部跳转、301永久跳转、302临时跳转。
三者区别在于内部跳转的URL不会改变,搜索引擎会收录这个URL,只能用rewrite实现,例如http://www.littz.cn/viewnews-340.html,在地址栏看到的还是这个,虽然服务器处理的实际上是http://www.littz.cn/index.php?action-viewnews-itemid-340
301跳转:URL改变跳转,可以用php的header、html的meta、javascript或者rewrite规则实现。例如访问http://www.littz.cn/html/2009/340.html,会跳转到http://www.littz.cn/viewnews-340.html这个地址。因为搜索引擎原来收录的URL是前者,我不想丢掉任何链接。同时写了301跳转之后,搜索引擎过一段时间会将收录的页面更新到新的URL上。
302跳转和301差不多,不过据说百度不认识而Google认识,当然我没证实过。

灵感:有网友提问,那我能不能写个rewrite实现让https://discuz.dismall.com跳转到http://www.littz.cn呢,这样我的博客不就访问量非常大了?哈哈,可以实现,不过不是用rewrite,用域名劫持

rewrite部分,快速入门就不讲RewriteEngine和RewriteCond了,只说RewriteRule。
RewriteRule顾名思义,伪静态规则。格式为:
  1. RewriteRule 正则表达式 目标 [类型]
复制代码
RewriteRule做的操作,可以理解为,判断request请求是否符合 第一段的“正则表达式”,如果符合规则 转给 “目标” 处理,那是内部跳转还是301跳转呢,由“类型”决定。

什么是正则表达式?正则表达式 可以理解为很高级的字符串匹配判断语句。例如我们写程序的时候,if ($a == abcdef) {;},那么仅仅只能判断$a是否等于“abcdef”。如果我想$a匹配“ab{任意一个字符}def”这个字符串 就可以呢,有些网友会想到windows用的通配符,?代表一个任意字符,*代表任意个任意字符。正则表达式比这个简单的相等判断、通配符判断更多复杂条件,基本能使用所有的场合。

常见正则表达式的字符串匹配条件:
^ 当且仅当字符开始
$ 当且仅当字符结束
. 任意单个字符
* 0或更多个
+ 1或更多个
? 0或1个
{n,m}  n到m个
() 分组
| 或
[a-z] a~z集合内任意一个字符
[] 集合内任意一个字符
[^] 不在集内的任意一个字符
\ 转义专用

正则表达式中为避免判断歧义,必要时应使用()分组以及\转义。
正则表达式只会匹配DOCUMENT_URI部分,不会看主机头和GET传递的参数。

目标:目标为普通字符串,不是正则表达式,有必要时,可以使用$1、$2这些第一段正则表达式匹配出来的变量。

类型:,[L]表示如果成功匹配这条RewriteRule,则退出rewrite不会继续判断下一条RewriteRule,[NC]匹配忽略大小写。默认为内部跳转,如果写[R=301] 则为301跳转。

评分

4

查看全部评分

 楼主| littlehz 发表于 2009-7-24 17:22:55 | 显示全部楼层
本帖最后由 littlehz 于 2009-7-25 00:16 编辑

常见规则解读:

  1. RewriteRule (.*) /test.html [L,R=301]
  2. #请求的任意URI 301跳转到/test.html
  3. RewriteRule ^(.*)$ /test.html [L,R=301]
  4. #这句其实效果和前一个一样,只是判断条件为当且仅当任意字符开始任意字符结束。

  5. RewriteRule ^(.*) https://discuz.dismall.com/$1 [R=301,L]
  6. #把当前主机收到的所有请求全部跳转到https://discuz.dismall.com/主机,$1这个变量为前面匹配的任意多个字符。适用于整体更换域名,本规则写在原域名下。

  7. RewriteRule ^/abc/(.*) /def/$1 [R=301,L]
  8. #匹配以/abc/开始的请求,跳转到/def/,$1为之前匹配的任意多个字符。301跳转。
  9. #例如请求http://www.littz.cn/abc/jjjjjwerwerew.html,会301跳转到http://www.littz.cn/def/jjjjjwerwerew.html,相当于给def目录建立了一个别名abc。

  10. RewriteRule ^/type-([0-9]+).html$ /type.php?typeid=$1 [L]
  11. #匹配以/type-开始的,并且后面接了1个或者多个数字,再后面接上.html的请求,并且以其结束的。内部跳转至/type.php?type=$1处理,$1为[0-9]+匹配得到的数字。
复制代码
官方的SS for Apache Rewrite规则解读
  1. <IfModule mod_Rewrite.c>
  2. #如果Apache安装并启用了mod_Rewrite.c模块

  3. RewriteEngine On
  4. #启用Rewrite
  5. ###Rewrite 系统规则请勿修改

  6. RewriteRule ^/([0-9]+)/spacelist(.+)$ /index.php?uid/$1/action/spacelist/type$2 [L]
  7. # 开始/{1个或多个数字}/spacelist{1个或多个任意字符}结束,内部跳转到 /index.php?uid/{匹配的数字}/action/spacelist/type{匹配的1个或多个任意字符} 处理

  8. RewriteRule ^/([0-9]+)/viewspace(.+)$ /index.php?uid/$1/action/viewspace/itemid$2 [L]
  9. # 开始/{1个或多个数字}/viewspace{1个或多个任意字符}结束,内部跳转到 /index.php?uid/{匹配的数字}/action/viewspace/itemid{匹配的1个或多个任意字符} 处理

  10. RewriteRule ^/([0-9]+)/viewbbs(.+)$ /index.php?uid/$1/action/viewbbs/tid$2 [L]
  11. # 开始/{1个或多个数字}/viewbbs{1个或多个任意字符}结束,内部跳转到 /index.php?uid/{匹配的数字}/action/viewbbs/tid{匹配的1个或多个任意字符} 处理

  12. RewriteRule ^/([0-9]+)/(.*)$ /index.php?uid/$1/$2 [L]
  13. # 开始/{1个或多个数字}/{任意个任意字符}结束,内部跳转到 /index.php?uid/{匹配的数字}/{匹配的任意个任意字符} 处理

  14. RewriteRule ^/([0-9]+)$ /index.php?uid/$1 [L]
  15. # 开始/{1个或多个数字}结束,内部跳转到 /index.php?uid/{匹配的数字}处理

  16. RewriteRule ^/action(.+)$ /index.php?action$1 [L]
  17. # 开始/action{任意个任意字符}结束,内部跳转到 /index.php?action/{匹配的任意个任意字符}处理

  18. RewriteRule ^/category(.+)$ /index.php?action/category/catid$1 [L]
  19. # 开始/category{任意个任意字符}结束,内部跳转到 /index.php?action/category/catid{匹配的任意个任意字符}处理
  20. #例如http://www.littz.cn/category-1.html,实际是发给了http://www.littz.cn/index.php?action/category/catid-1.html

  21. RewriteRule ^/viewnews(.+)$ /index.php?action/viewnews/itemid$1 [L]
  22. # 开始/viewnews{任意个任意字符}结束,内部跳转到 /index.php?action/viewnews/itemid{匹配的任意个任意字符}处理
  23. #例如http://www.littz.cn/viewnews-340.html,实际是发给了http://www.littz.cn/index.php?action/viewnews/itemid-340.html

  24. RewriteRule ^/viewthread(.+)$ /index.php?action/viewthread/tid$1 [L]
  25. # 开始/viewthread{任意个任意字符}结束,内部跳转到 /index.php?action/viewthread/tid{匹配的任意个任意字符}处理

  26. RewriteRule ^/mygroup(.+)$ /index.php?action/mygroup/gid$1 [L]
  27. # 开始/mygroup{任意个任意字符}结束,内部跳转到 /index.php?action/mygroup/gid{匹配的任意个任意字符}处理
  28. </IfModule>
复制代码
至此,对rewrite应该有一定了解。可以开始自写rewrite了。

下面说的是用rewrite的方法实现,当然可以用其他方法实现,多一种方法。
@@1 原来我用www.abc.com的网址进我的网站,现在有新的网址www.littz.cn,但是不想丢掉原URL的链接,又希望所有通过原URL访问的自动跳转到新URL,怎么办呢?
首先保证www.abc还是受你控制的,在www.abc.com的服务器下写rewrite规则
  1. RewriteRule ^(.*) http://www.littz.cn/$1 [R=301,L]
复制代码
@@2 原来我的ss放在http://www.littz.cn/ss,现移动到上级目录了,http://www.littz.cn,新URL已经能访问,也不想丢掉原URL的链接,又希望所有通过原URL访问的自动跳转到新URL,怎么办呢?
www.littz.cn的对应的目录下写rewrite规则。(使用于ss路径已经不会再使用的)
  1. RewriteRule ^/ss/(.*) http://www.littz.cn/$1 [R=301,L]
复制代码
@@3 原来我的ss放在http://www.littz.cn/,现移动到supesite目录了,http://www.littz.cn/supesite,新URL已经能访问,也不想丢掉原URL的链接,又希望所有通过原URL访问的自动跳转到新URL,同时http://www.littz.cn/的留给我自己写的一些页面用,怎么办呢?
这个时候规则就不能做(.*)的任意判断跳转了。
一、分析哪些URL是需要跳转的,跳转之后到哪里,哪些链接容易出现匹配冲突。
二、确定跳转关系,书写rewrite规则
三、检查rewrite规则,尤其是容易产生匹配冲突的情况。

本例中,要做的判断是仅为SS的URL才跳转至supesite目录中。

  1. RewriteRule ^/([0-9]+)/spacelist(.+)$ /supesite/$1/spacelist$2 [L,R=301]
  2. RewriteRule ^/([0-9]+)/viewspace(.+)$ /supesite/$1/viewspace$2 [L,R=301]
  3. RewriteRule ^/([0-9]+)/viewbbs(.+)$ /supesite/$1/viewbbs$2 [L,R=301]
  4. RewriteRule ^/([0-9]+)/(.*)$ /supesite/$1/$2 [L,R=301]
  5. RewriteRule ^/([0-9]+)$ /supesite/$1 [L,R=301]
  6. RewriteRule ^/action(.+)$ /supesite/action$1 [L,R=301]
  7. RewriteRule ^/category(.+)$ /supesite/category$1 [L,R=301]
  8. RewriteRule ^/viewnews(.+)$ /supesite/viewnews$1 [L,R=301]
  9. RewriteRule ^/viewthread(.+)$ /supesite/viewthread$1 [L,R=301]
  10. RewriteRule ^/mygroup(.+)$ /supesite/mygroup$1 [L,R=301]
复制代码
回复

使用道具 举报

 楼主| littlehz 发表于 2009-7-24 17:26:50 | 显示全部楼层
本帖最后由 littlehz 于 2009-7-25 00:34 编辑

常见问题解答:
%%1:根目录有文件,子目录也有文件,如何在根目录配置rewrite规则使其不影响子目录?
假设一个文件结构: /index.php,/home/index.php。我想通过/home-1.html实际是访问/index.php?homeid-1.html这个,而通过/home/view-124.html访问/home/index.php?bbsid-124.html这个。
如果简单的写了一条
  1. RewriteRule ^/home(.+)$ /index.php?homid-$1 [L]
复制代码
这条规则,当然可以把/home-1.html的请求转给/index.php?homid-1.html,但是想想是不是也会把/home/index.php的请求给了/index.php?homeid/index.php  ?
这就出现了规则匹配冲突问题,不想要被匹配的URL也跳转了,应该把这个rewrite写的严密些。
  1. RewriteRule ^/home-([0-9]+)\.html$ /index.php?homid-$1.html [L]
复制代码
这个就只会匹配/home-1.html而不会匹配/home/index.php,所以也就不会产生根目录的rewrite影响子目录。总之就是分析会造成冲突的URL,检查rewrite规则是否有多余的不够严密的
回复

使用道具 举报

lidq.jingwu 发表于 2009-7-24 17:30:21 | 显示全部楼层
顶一个,正在学
回复

使用道具 举报

sunj85 发表于 2009-7-24 17:33:02 | 显示全部楼层
本帖最后由 sunj85 于 2009-7-24 17:35 编辑

啊啊啊,littlehz把前两楼都占了

----------------------------------
最近被这个弄的很郁闷,不知道该怎么办了

我在我的虚拟主机的根目录安装了SS,子目录安装UCH,并对子目录绑定了二级域名。

记下来开启了SS的伪静态,并成功实现了伪静态,可是通过二级域名访问UCH却出现500错误,通过主域名+目录名的方式却可以正常访问。

想问下,SS的规则该怎么写才不会影响到子目录的访问
回复

使用道具 举报

waosoft 发表于 2009-7-25 14:29:00 | 显示全部楼层
留个名,关注这贴子,自己研究做Rewrite
回复

使用道具 举报

guoyu1321 发表于 2009-7-25 14:32:10 | 显示全部楼层
学习中  谢谢
回复

使用道具 举报

cgtest 发表于 2009-7-28 23:04:52 | 显示全部楼层
本帖最后由 cgtest 于 2009-7-28 23:12 编辑

看不到....金币的那部分,我没有
回复

使用道具 举报

cgtest 发表于 2009-7-28 23:10:34 | 显示全部楼层
本帖最后由 cgtest 于 2009-7-28 23:12 编辑

我连基本的还不会, 一级二级是静态, 详细内容也还是动态
回复

使用道具 举报

guoyu1321 发表于 2009-7-28 23:14:25 | 显示全部楼层
站位学习 www.iiapple.com 苹果网
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|Discuz! 官方站 ( 皖ICP备16010102号 )star

GMT+8, 2024-11-14 14:32 , Processed in 0.029343 second(s), 6 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表