URL重写之在IIS7中使用HttpModule,在IIS5和IIS6中使用 ISAPIRewrite实现无扩展名的URL重写(节选自福娃儿)

在IIS7中使用HttpModule 实现无扩展名的URL重写
上述的HttpModule方法在你要重写的URL含有.aspx 扩展名或者包含另一个被设置为ASP.NET处理的扩展名的情形下一切都工作。你这么做的话,不需要任何特定的服务器配置,你只要把你的应用拷贝到远程服务器,它会正常工作的。
但有的时候,你要重写的URL要么拥有一个不为ASP.NET处理的文件扩展名(譬如, .jpg, .gif,或 .htm),要么根本没有扩展名。譬如,我们也许要把这些URL呈示成公开的产品目录网页(注意,它们没有 .aspx 扩展名):
 
http:
// www.store.com/products/Books
http: // www.store.com/products/DVDs
http: // www.store.com/products/CDs
在 IIS5 和 IIS6 中,使用ASP.NET处理上面这样的URL不是很容易。 IIS  5 / 6  使得在ISAPI扩展(ASP.NET就是这样一个扩展)里非常难以重写这些类型的URLS。你需要做的是使用ISAPI过滤器在IIS请求管道(request pipeline)的较早期实现重写。我将在下面的第四个方法里示范如何在 IIS5 / 6  实现这样的重写。
但好消息是, IIS 
7 .0使得处理这类情形容易之极。你现在可以在 IIS 请求管道的任何地方执行一个HttpModule,这意味着你可以使用上面的URLRewriter 模块 来处理和重写无扩展名的URL(甚至是带有 .asp,.php,或 .jsp 扩展名的URL)。下面示范了你在IIS7中该如何配置:
 
<? xml version = " 1.0 "  encoding = " UTF-8 " ?>

< configuration >

  
< configSections >
    
< section name = " rewriter "  
             requirePermission
= " false "  
             type
= " Intelligencia.UrlRewriter.Configuration.RewriterConfigurationSectionHandler, Intelligencia.UrlRewriter "   />
  
</ configSections >
  
  
< system.web >
      
    
< httpModules >
      
< add name = " UrlRewriter "  type = " Intelligencia.UrlRewriter.RewriterHttpModule, Intelligencia.UrlRewriter "   />
    
</ httpModules >
    
  
</ system.web >

  
< system.webServer >

    
< modules runAllManagedModulesForAllRequests = " true " >
      
< add name = " UrlRewriter "  type = " Intelligencia.UrlRewriter.RewriterHttpModule "   />
    
</ modules >

    
< validation validateIntegratedModeConfiguration = " false "   />

  
</ system.webServer >

  
< rewriter >
    
< rewrite url = " ~/products/(.+) "  to = " ~/products.aspx?category=$1 "   />
  
</ rewriter >
  
</ configuration >
 
注意一下
< system.webServer > < modules > 部分设置为true的runAllManagedModulesForAllRequests属性。这个属性确保来自Intelligencia的UrlRewriter.Net模块(是在IIS7正式发布前编写的),会被调用,有机会重写到服务器的所有URL请求(包括文件夹)。上面的web.config文件非常酷之处在于:
1 ) 它在任何IIS7机器上都会工作,你不需要管理员在远程主机上启用任何东西,它也能在设置为中等信任安全等级(medium trust)的共享主机的环境场景下工作。
2 ) 因为我在 < httpModules > 和 IIS7 的 < modules >  部分同时配置了UrlRewriter,我既能在 VS内置的web服务器(即Cassini)中,也能在IIS7下使用同样的URL重写规则。两者完全支持无扩展名的URL重写。这使得测试和开发非常容易。
IIS 
7.0  将在今年的晚些时候作为Windows Longhorn服务器的一部分发布,将在几个星期内随Beta3版本的发布支持go - live许可。由于添加到IIS7中的所有的新宿主(hosting)特性,我们预期主机供应商将会非常快地开始积极提供IIS7账号,这意味着你应该很快就可以开始利用上述的无扩展名的URL重写支持。我们将在 IIS7 RTM 时段里发布一个为微软所支持的URL重写模块,该模板是免费的,你可以在IIS7上使用,并且这模块将对你web服务器上的所有内容的高级URL重写场景提供很好的支持。
样例下载:我建立的一个使用IIS7和UrlRewriter.Net模块展示无扩展名URL重写技术的样例应用可以在这里下载。

's ISAPI Rewrite: 他们提供一个99美元(可免费试用30天)的ISAPI URL重写产品完整版,以及一个免费的轻量级版本。
·       Ionic's ISAPI Rewrite: 这可以免费下载(源码和可执行文件都可以下载)
我没亲手用过上面的产品,虽然我听过到对这2个产品的好评。Scott Hanselman和 Jeff Atwood 最近都写了精彩的博客贴子讲述使用这些产品的体验,同时提供了一些如何在这些产品中配置匹配规则的例子。Helicon Tech的ISAPI Rewrite的规则使用跟 Apache的mod_rewrite同样的句法,譬如(取自Jeff的博客贴子):
 
[ISAPI_Rewrite]
# fix missing slash on folders
# note, 
this assumes we have no folders with periods!
RewriteCond Host: (.
*)
RewriteRule ([
^.?]+[^.?/]) http://$1$2/ [RP]

# remove index pages from URLs
RewriteRule (.
*)/default.htm$ $1/ [I,RP]
RewriteRule (.
*)/default.aspx$ $1/ [I,RP]
RewriteRule (.
*)/index.htm$ $1/ [I,RP]
RewriteRule (.
*)/index.html$ $1/ [I,RP]

# force proper www. prefix on all requests
RewriteCond 
%HTTP_HOST ^test.com [I]
RewriteRule 
^/(.*) http://www.test.com/$1 [RP]

# only allow whitelisted referers to hotlink images
RewriteCond Referer: (
?!http://(?:www.good.com|www.better.com)).+
RewriteRule .*.(?:gif|jpg|jpeg|png) /images/block.jpg [I,O] 
 
一定要去读一下Scott和Jeff的贴子以了解这些ISAPI 模块的详情,以及你都能用它们做些什么。
注:使用ISAPI过滤器的一个坏处是,共享主机环境一般不允许你安装这样的组件,所以你要用它们的话,你要么需要一个专用的虚拟主机服务器,要么需要一个专用的主机服务器。但,如果你有一个主机计划允许你安装ISAPI的话,这会在IIS5
/6下会提供最大的灵活性,让你过渡到IIS7推出为止。
在URL重写里处理ASP.NET PostBack
大家在使用ASP.NET和重写URL时经常遇到的一个疑难杂症跟处理postback场景有关。具体地来说,当你在一个网页上放置一个 
<form runat="server"> 控件时,ASP.NET 会自动地默认输出标识的action属性指向当前所在页面。当使用URL重写时,会出现这样的问题,<form> 控件显示的URL不是原先请求的URL(譬如,/products/books),而是重写过后的URL(譬如,/products.aspx?category=books)。这意味着,当你做一个postback到服务器时,URL不再是你原先干净利落的那个了。
在 ASP.NET 
1.0 和1.1 中,大家经常诉诸于继承<form> 控件生成他们自己的控件,来正确地输出要使用的action属性。虽然这可以工作,但结果有点乱,因为这意味着你需要更新你所有的页面来使用这个另外的表单控件,而且有时在Visual Studio所见即所得设计器里也会遇上问题。
好消息是,在ASP.NET 
2.0中,有个比较干净的诀窍你可以用来重写<form>控件的action属性。具体地来说,你可利用新的ASP.NET 2.0控件适配器扩展架构来定制控件的输出,用你提供的值来覆盖action属性的值。这不要求在你的.aspx页面里做任何编码改动,而只要在你的/app_browsers文件夹里添加一个.browser文件,注册使用一个控件适配类即可输出新的action属性。
 
你可在这里查看一个我创建的样例实现,其展示了该如何实现与URL重写协作的表单控件适配器(Form Control Adapter) 。它在我上面使用的第一个(Request.PathInfo),第二个方法(UrlRewriter.Net 模块)中都工作,它使用Request的RawUrl属性获取原先没改写过的 URL来显示。而在第四个方法(ISAPIRewrite过滤器)中,你可以获取ISAPI过滤器保存在Request.ServerVariables[
"HTTP_X_REWRITE_URL"] 中的原先的URL值。
我上面的FormRewriter类实现在标准的ASP.NET和ASP.NET AJAX 
1.0网页上应该都工作(如果你遇上问题的话,告诉我一声)。
正确地处理CSS和图像引用
不少人在第一次使用URL重写时,有时会遇上一个疑难杂症,就是他们发现他们的图像和CSS样式表引用有时会停止工作。这是因为他们在HTML网页里有对这些文件的相对引用,当你开始在应用里重写URL时,你需要意识到浏览器经常会在不同的逻辑层次结构层上(logical hierarchy levels)请求文件,而不是实际存储在服务器上的东西。
譬如,如果我们上面的
/products.aspx网页对.aspx 网页里的logo.jpg有一个相对引用,但是通过 /products/books.aspx这个URL来请求的,那么浏览器在显示网页时,将会发出一个对/products/logo.jpg的请求,而不是对/logo.jpg的请求。要正确地引用这个文件,确认你用根目录限定了(root qualify)CSS和图像引用(“/style.css”,而不是 “style.css”)。对于ASP.NET控件,你也可以使用“~”句法从你应用的根目录来引用文件(譬如,<asp:image imageurl="~/images/logo.jpg" runat="server"/>) 。


在IIS5和IIS6中使用 ISAPIRewrite 来实现无扩展名的URL重写
如果你不想等到IIS7出来才利用无扩展名的URL重写,那么你最好的措施是使用ISAPI过滤器来重写URL。我知道有2个ISAPI过滤器方案,你也许要去看一下:
·       Helicon Tech
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值