zc's blogs

易讯DIGG网 - 与您的朋友一起阅读与分享
随笔 - 205, 文章 - 36, 评论 - 556, 引用 - 22
数据加载中……

IIRF(Ionic's Isapi Rewrite Filt er)入门,在IIS上重写Url

每一次看scottgurBLOG总能收获意外的惊喜^_^。在他的这篇BLOGTip/Trick: Url Rewriting with ASP.NET(感谢思归)中,描述了有关在ASP.NET重写URL的各种方法。而我这篇文章不会涉及如何在ASP.NET重写URL,只是简单介绍IIRF(为了方便少写几字,以后的Ionic's Isapi Rewrite Filter将全部简写)如何在IIS下面实现URL的重写。

介绍

 IIRF是一款开源的重写URL过滤器,类似于ApacheURL重写,基于VC8.0(可以用Visual Studio2005Visual C++ 2005 Express重新编译)开发。它可以运行在IIS5.0+,支持ASP,ASP.NET,PHP等许多格式。相对比ASP.NET2.0自带的URL重写,具有更好的性能和许多我们所需要特性,重要的一点在于:它可以支持无扩展名的URL(例如:cnlbogs.com/****,你无需在创建一个默认的default.aspx文件,IIRF自动会帮你解析),让URL更加的方便我们记忆,也能进一步提高搜索的排名?IIRF能够在aspnet_isapi提前捕获我们所请求的URL进行处理,如果我们访问cnlbogs.com/a.aspx,需要获取cnlbogs.com/a.htm,步骤需要(iis-aspnet_isapi),通过IIRF,我们可以直接跳aspnet_isapi.dll,直接访问a.htm,要知道,这种方式在ASP.NET是无法实现的。

 IIRFASP.NET重写URL一样,它也是基于正则的方式来匹配,具有LOG记录,请求的条件判断。还是进入正题吧。 

安装

 IIRF安装需要我们手动操作来完成。不过。也是很方便了。

1 IsapiRewrite4.dll, IsapiRewrite4.ini复制到c:\windows\system32\inetsrv(你也可以复制到其它适当的文件夹下面)

IsapiRewrite4.iniIIRF配置文件,每次该文件更改之后,IIRF会自动重新加载该文件,无需重启IIS来重新加载配置,如果您修改后INI文件后格式不正确,IIRF将会自动获取最后正确加载的配置文件。

2 打开IIS管理器,选择“默认网站”,右击“属性”,选择“ISAPI筛选器”,点击“添加”,输入筛选器名称:Ionic Rewriter,可执行文件选择上面复制到c:\windows\system32\inetsrv下面的IsapiRewrite4.dll文件,点“确定”。

3重启IISADMIN service服务。(在计算机管理----windows服务里面)

4 完成。

日志

IIRF
能够将INI配置文件加载,用户的URL请求记录都会保存到指定的日志文件里。因为它具有很大的性能开销,因此建议将它日志的记录等级设为0,只有
为了方便调试的时候时候,可以设置为5

RewriteLog <filename stub>  保存的日志路径,如 c:\temp\iirfLog.out
RewriteLogLevel {0,1,2,3,4,5} 日志的等级,默认值为0

0 –不会记录日志
1- 少许的日志
2-  比较多的日志
3- 比较详细的日志
4- 详细的日志(4),并会跟踪server variable和替换的字符串。
5- 详细的日志(5),包括日志文件更改的事件,建议方便调试的时候使用

正则

正则的语法跟.NET一样,只不过是格式不一样而已。所以我也不在详细介绍。具体有关正则的说明大家可以用GOOGLE搜索。

格式:
RewriteRule <url-pattern> <replacement-string>   [<modifiers>]
url-pattern:匹配的正则表达式(必需)
replacement-string:要替换的字符串(必需)
modifiers:有关对RewriteRule的操作标记。可选选项。在下面我会说明

默认下IIRF的url-pattern,replacement-string正则的前面已经带了主机头的。

为了方便描述,直接看几个示例
(以下示例基本全部来源IIRF文档)

RewriteRule  ^/original/(.*).php  /modified/$1.aspx

源:http://xxx/original/index.php

目标:http://xxx/modified/index.aspx

RewriteRule  ^/dinoch/album/([^/]+)/([^/]+).(jpg|JPG|PNG)   /chiesa/pics.aspx?d=$1&p=$2.$3

源:http://xxx/dinoch/album/30/1.jpg

目标:http://xxx/chiesa/pics.aspx?d=30&p=1.jpg

 比较简单,主要还在于modifiers的功能。下面列举了它的所有值,允许组合([R,L])

   R = Redirect(URL跳转到<replacement-string>地址)
   NF = Not found(返回404错误给用户,但该文件并未移除,还是保留在网站中)
   L = Last test if match(如果已经匹配,将不在继续匹配下去)
   F = Forbidden(跟NF标志相似,)
   I = Do case-insensitive matching
   U = Store original url in server Variable HTTP_X_REWRITE_URL(保存原始的url到HTTP_X_REWRITE_URL服务器变量中。)

[R]  or [R=code]
就像跟我们在ASP.NET使用的Redirect方法一样,重新改变浏览器的方向,跳转到新的指定的URL中。
[R=code]允许我们指定特定的HTTP状态返回码。只能介于301到399。如果超出这个范围。默认会是使用302状态。
RewriteRule ^/goto.aspx?r=(.*)$ $1 [R]
源:http://xxx/goto.aspx?r=http://www.google.com/
目标:http://www.google.com


[L]
上面已经简单介绍过。不在说明

[NF]
上面已经简单介绍过。它还可以跟RewriteCond一起配合,来实现自定义的404错误请求。
特别要注意,你所要匹配的文件必须存在,替换的字符串不允许是存在文件名
RewriteRule ^/1008.aspx$ /1.aspx [NF]
1008.aspx文件需要存在,1.aspx不存在,否则无法正常达到我们的结果。
(很奇怪,我不知道是不是我搞错了。但我最终测试的结果确实是这样,文档也没详细说明过,有知道的朋友可以告诉我一下原因)

[F]
不在说明。

[I]
模糊匹配

[U]
保存原始的url到HTTP_X_REWRITE_URL服务器变量中。
在ASP.NET你可以用Request.ServerVariables["HTTP_X_REWRITE_URL"]获取原始值。

RewriteCond
RewriteCond <test-string> <pattern> [<modifier flag[,...]>]
类似于条件判断,并且允许多个条件,OR,AND。只有当RewriteCond的Server Variable 匹配所指定的正则表达,RewriteRule才会执行。比如:
RewriteCond %{REMOTE_ADDR} ^(127.0.0.1)$
RewriteRule ^/(.*).aspx$ /$1.aspx
如果我们访问网站的地址的IP来源于127.0.0.1,那么,允许 RewriteRule ^/(.*).aspx$ /$1.aspx

RewriteCond %{REMOTE_ADDR} ^(127.0.0.1)$ [OR]
RewriteCond %{REMOTE_ADDR} ^(192.168.0.10)$
RewriteRule ^/(.*).aspx$ /$1.aspx
添加了OR来多个条件判断

RewriteCond %{REMOTE_ADDR}   ^(?!127.0.0.1)([0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3})(.*)$
RewriteRule  ^/(?!redirected.htm)(.*)$      /redirected.htm

Modifier flags有二个值
I=模糊匹配
OR=逻辑判断

从IIRF的RewriteCond的功能上来说,确实很灵活,不知道跟IIS7的重写怎么样,嘻嘻。还没瞧见过呢*^_&。另外。RewriteCond的[Patterns]可以带下面几个参数
 -d
  Treats the TestString as a pathname and tests if it exists,
  and is a directory.
TestString是一个路径名称,并且存在这个路径
 -f
  Treats the TestString as a pathname and tests if it exists and
  is a regular file.
TestString是一个路径名称,并且是一个存在的文件
  -s
  Treats the TestString as a pathname and tests if it exists and
  is a regular file with size greater than zero.
TestString 是一个路径名称,并且存在文件超过0字节

如文档所使用的例子
(1)RewriteCond %{HTTP_URL}             (/|\.htm|\.php|\.html|/[^.]*)$   [I] )
(2)RewriteCond %{REQUEST_FILENAME}     !-f
(3)RewriteCond %{REQUEST_FILENAME}     !-d                                 
(4)RewriteRule ^.*$                    /index.aspx                      [U,L]
(1)如果URL是以htm,php,html(模糊匹配),
(2)URL不是存在文件
(3)URL不是请求的路径
(4)将所有请求跳转到index.aspx,保存原始的URL,之后不在对此进行匹配

在如
RewriteCond  %{HTTP_USER_AGENT}  ^Mozilla.*
RewriteRule  ^/$                 /homepage.max.html  [L]

IIRF其它配置属性
IterationLimit {integer}从指定的integer后开始匹配RewriteRule组。如果超出RewriteRule个数,默认将会从第8个开始。
MaxMatchCount {integer} RewriteRule组的总个数。
RewriteLog <filename stub> 日志路径
RewriteLogLevel {0,1,2,3,4,5} 日志的等级

一个常见问题
在刚安装IIRF之后就测试一下ASP.NET下面的URL,发现还是跟以前ASP.NET重写URL有一样的问题:无法改写Form下面的action的路径,而我们这时使用Request.RawUrl获取原始的URL是为空的。也许你开始注意到了我上面写过的RewriteRule的modifiers选项[U]。我们可以通过将原始的URL保存到服务器变量中。然后通过Request.ServerVariables[name]来获取。然后重写action的值就可以了。

代码1

后记:
IIRF已经分析的差不多了。从上面可以看出,功能确实很强大,而且配置也很灵活。发现自己也慢慢喜欢上它了。嘿嘿。重要的是。它是免费,开源的。

为自己小小的鼓掌一下。嘻嘻。写这篇随笔真不容易。希望能给大家一个帮助。另外,由于自己水平有限,上面也许有描述错误的地方或不清楚的地方还请指出,有则改之,无则加勉:)

最后,祝大家2007年的第一个周未愉快*^_^*

[2007-09-01]
http://zhangsichu.com/blogview.asp?Content_Id=82
这里已经有人实现了二级域名的重写,大家可以去看看.感谢 tombom 提供的信息.

IIRF网站:http://cheeso.members.winisp.net/IIRF.aspx

posted on 2007-03-02 21:33 小春 阅读(5996) 评论(33)  编辑 收藏 网摘 所属分类: ASP.NET第三方工具.NET开发

评论

#1楼   回复  引用  查看    

不错, 尤其是那个选项U
2007-03-02 22:47 | Ariel Y.      

#2楼   回复  引用  查看    

IIS7可以使用托管代码编写模块。

其实就是把ASP.NET紧紧地结合了IIS。
2007-03-02 23:11 | Jeffrey Zhao      

#3楼   回复  引用    

其实 IIRF 的 U 在IIS6 + Kernal caching 的时候是有问题的。
具体可以看 IIRF 自己的说明。
2007-03-03 00:11 | robinz-hbifts[未注册用户]

#4楼   回复  引用    

@robinz-hbifts
谢谢。我在写的时候也注意到这个问题。但有几点因为没明白。
一个是关于SF_NOTIFY_LOG事件,kernel response cache的输出,但是我测试的时候并没有他所说的这个问题。也许是我还没看明白的原因。
2007-03-03 00:53 | 小春[未注册用户]

#5楼   回复  引用  查看    

东西是好了,可是没有自己的服务器,好东西也用不上。


传音石——网罗天下资源 http://www.massany.com">http://www.massany.com
2007-03-03 08:37 | 命运有自己的梦!      

#6楼   回复  引用    

有时间试用一下

#7楼   回复  引用  查看    

不错,不知道稳定性和速度是否可以与apache+mod_rewrite有一拼
但是总算是有开源免费的了,收藏...
2007-03-03 09:10 | 补丁      

#8楼   回复  引用    

在iis->属性->主目录->配置->映射 中添加映射行不行呢?

另外那些RewriteRule是写在IsapiRewrite4.ini文件中吗?

2007-03-03 10:31 | Yao[未注册用户]

#9楼   回复  引用    

@Yao
映射了是可以的,但有一点就是,直接映射了你还需要自己重写URL
RewriteRule是写在IsapiRewrite4.ini文件中的。

@命运有自己的梦!
可以在自己机器上玩玩。嘻嘻
2007-03-03 12:23 | 小春[未注册用户]

#10楼   回复  引用    

很久以前就在用了。这个组件有一个问题。
这样的Rewrite会出错。
RewriteRule ^/Search?(.*) /Search.asp?$1
例如 /Search?Key=Test 会影射到 /Search.asp??key=test
这个问题当时就那么扔了。没具体看。
代码我看了。纯C写的。不容易
2007-03-03 20:57 | JoeLee[未注册用户]

#11楼   回复  引用  查看    

@robinz-hbifts

那岂不就是说在IIS6下应用有严重的性能问题啊?
因为ASP.net只要用PostBack一定要知道这个重写之前的URL

还有别的办法吗?
2007-03-03 23:46 | Ariel Y.      

#12楼   回复  引用  查看    

@JoeLee
出错是因为对?的理解
2007-03-05 09:24 | 补丁      

#13楼   回复  引用    

我想用这个实现二级域名重写功能,但是没有成功!

不知道谁能给点帮助不!

先谢谢了!
2007-03-16 09:35 | 天客[未注册用户]

#14楼   回复  引用    

关于form action的问题,看这篇文章.
http://blog.joycode.com/scottgu/archive/2007/03/01/94004.aspx
通过添加browser文件来解决.
2007-03-19 01:03 | gameboy[未注册用户]

#15楼   回复  引用    


@天客
类似于,你可以根据http_host的服务器变量来叛变
RewriteCond %{HTTP_HOST} ^(.*).website1.com$
RewriteRule ^/(.*)$ /website1/default.htm [L]
2007-03-19 22:06 | 小春[未注册用户]

#16楼   回复  引用    

楼上能不能说的再清楚些? 这个配置应该如何写?

例如,想将 abc.test.com -> www.test.com/xx.aspx?id=abc
2007-03-20 17:06 | 砖家[未注册用户]

#17楼   回复  引用    

前段时间在仔细看了看。发现无法支持二级域级的。
但是,如果去修改源代码的话。还是可以实现的。可惜。我不懂VC
2007-04-03 17:51 | 小春[匿名][未注册用户]

#18楼   回复  引用    

我上次找iirf似乎没找到.或者找到了不知道放哪儿了。
春春哪儿下的??

2007-04-10 14:53 | yiyioo[未注册用户]

#19楼   回复  引用    

嗯嗯
那是相当的不错
正看那英文原版博客头疼呢,不想到你写得比他还详细呢!!
2007-07-02 16:25 | 流浪随风[未注册用户]

#20楼   回复  引用    

大小写敏感问题不知如何解决?
2007-07-16 14:38 | Dove[未注册用户]

#21楼   回复  引用  查看    

只有在IIS上才有这个问题,UNIX系统是大小写敏感的。

我觉得大小写问题不用在意,都小写即可。

当然不乏特殊需求
2007-07-16 20:55 | Ariel Y.      

#22楼   回复  引用    

@补丁
不是的。这个问题已经解决了。重写规则的文件名里不能用Search这个关键字。
RewriteRule ^/Search?(.*) /SiteSearch.asp?$1
把Search.asp改成SiteSearch.asp就OK了。
2007-07-23 13:14 | JoeLee[未注册用户]

#23楼   回复  引用    

二级域名重写
abc.test.com -> www.test.com/xx.aspx?id=abc


http://zhangsichu.com/blogview.asp?Content_Id=82
有说明,好像这个人实现了。
2007-08-21 16:05 | tombom[未注册用户]

#24楼[楼主]   回复  引用  查看    

@tombom
谢谢.已经收藏了.呵
2007-09-01 18:33 | 小春      

#25楼   回复  引用    

能给个.net的例子吗?我配置的好象不对。表达式也不对。谢谢了。
2007-12-05 17:45 | remember[未注册用户]

#26楼   回复  引用    

iirf支持伪静态吗?
2007-12-05 18:15 | remember[未注册用户]

#27楼   回复  引用    

@remember
您好.我不清楚伪静态是什么.
IIRF只是一个处理IIS请求,重写URL而已,不仅仅只适合.NET的.根据我上面所说的步骤一步步下来应该是可以成功的.配置不对我想有可以是你的正则表达式的原因.你可以开启DEBUG模式来看看是哪里出现问题.
2007-12-11 11:58 | 春[未注册用户]

#28楼   回复  引用    

如果我要使我的一部分规则只对一个站点有效改如何设置呢?
好像RewriteCond %HTTP_HOST ^test\.com [I]这样更不无效果。
2008-04-17 17:39 | 小溪[未注册用户]

#29楼   回复  引用  查看    

感谢 收藏之 呵呵
2008-05-31 12:06 | 黄明      

#30楼   回复  引用    

不错,博主应该提供更多的场景应用实例啊,期待
2008-09-27 22:26 | 招聘大象[未注册用户]

#31楼   回复  引用    

我想访问www.aaa.com/mm.asp?123时把http://www.bbb.com:81/mm.asp?123的内容显示出来,重写的规则要怎么写

RewriteRule ^/goto.aspx?r=(.*)$ $1 [R]这条规则我试过也不行,这是什么问题

isapi里显示加载成功的!
2009-03-23 16:19 | gghandsome[未注册用户]

#32楼   回复  引用    

我有2个问题请教

1、ASP.NET 中URl重写后原google收录的网页处理的问题
我的网站发布了已经半年了,现在想URL静态化,用了IIRF(Ionic's Isapi Rewrite Filter)做网页重定向
在IsapiRewrite4.ini文件中
#重写/b-100.html 到 /Books/Content.aspx?ResourceID=100
RewriteRule ^/b-100.html$ /Books/Content.aspx?ResourceID=100 [U,L]

现在为了保留google中保留的 /Books/Content.aspx?ResourceID=100 网页价值 做一个301的重定向。

处理旧地址,在IsapiRewrite4.ini文件中添加
RewriteRule ^/b.html$ /b-100.html [RP,I]
这样就如果访问/b-100.html或/Books/Content.aspx?ResourceID=100
都出现无限的循环。这样做这个重定向呢?

2、关于URL地址标准化 实现 http://www.abc.com/Default.aspx与http://www.abc.com/" target="_new" rel="nofollow">http://www.abc.com/Default.aspx与http://www.abc.com/ 都实现指向http://www.abc.com/
的重定向。
在ISAPI_Rewrite
RewriteRule ([^?]*)(Default)\.aspx$ $1 [RP,I,U]
能实现
但在IIRF(Ionic's Isapi Rewrite Filter)
RewriteRule ([^?]*)(Default).aspx$ $1 [RP,I,U]
中为什么不行?
在ISAPI_Rewrite 与IIRF(Ionic's Isapi Rewrite Filter)的区别是IIRF不需要转义字符/
2009-05-17 08:25 | abc121211[未注册用户]

#33楼   回复  引用    

我有2个问题请教

1、ASP.NET 中URl重写后原google收录的网页处理的问题
我的网站发布了已经半年了,现在想URL静态化,用了IIRF(Ionic's Isapi Rewrite Filter)做网页重定向
在IsapiRewrite4.ini文件中
#重写/b-100.html 到 /Books/Content.aspx?ResourceID=100
RewriteRule ^/b-100.html$ /Books/Content.aspx?ResourceID=100 [U,L]

现在为了保留google中保留的 /Books/Content.aspx?ResourceID=100 网页价值 做一个301的重定向。

处理旧地址,在IsapiRewrite4.ini文件中添加
RewriteRule ^/Books/Content.aspx?ResourceID=100$ /b-100.html [RP,I]
这样就如果访问/b-100.html或/Books/Content.aspx?ResourceID=100
都出现无限的循环。这样做这个重定向呢?

2、关于URL地址标准化 实现 http://www.abc.com/Default.aspx与http://www.abc.com/" target="_new" rel="nofollow">http://www.abc.com/Default.aspx与http://www.abc.com/ 都实现指向http://www.abc.com/
的重定向。
在ISAPI_Rewrite
RewriteRule ([^?]*)(Default)\.aspx$ $1 [RP,I,U]
能实现
但在IIRF(Ionic's Isapi Rewrite Filter)
RewriteRule ([^?]*)(Default).aspx$ $1 [RP,I,U]
中为什么不行?
在ISAPI_Rewrite 与IIRF(Ionic's Isapi Rewrite Filter)的区别是IIRF不需要转义字符/
2009-05-17 08:28 | abc121211[未注册用户]



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 662217




相关文章:

相关链接: