通常我们在浏览器中输入一个url,当返回结果时地址栏的url改变了.例如cnblogs,输入http://huankfy.cnblogs.com,结果反馈回来后地址为http://www.cnblogs.com/huankfy.在其他的站点我们同样可以见到这种应用,尤其是一些提供blog服务和bbs站点.当输入http://site.com/2004给出2004年所有的文章,输入http://site.com/2004/5会给出2004年5月份的所有文章(在此site只为举例方便,不一定会有这个站点).这就是url重写的应用.这种好处: 符合url简单 易于键入 能够使人很好的理解站点的结构. 允许用户通过删除 URL 的组成部分来浏览站点 除此之外,还方便站点重组.以免导致链接失效或书签过期.
URL重写方式 IIS筛选器实现IIS web服务器上对url重写:在asp.net之前对url重写采用的是ISAPI筛选器.已经有非常好的商业ISAPI筛选器组件.使用asp.net对url重写:由于asp.net引擎和iis非常相似,所以对url的重写这种方式成为可能. 首先看看iis对请求的处理.当请求传入iis服务器时,iis将会检查拓展名以决定如何进行处理.iis自行处理静态的内容,如html,图像等其他静态内容.对于动态内容,iis会将请求路由到ISAPI扩展,由对应的处理引擎或程序进行处理,最后将处理的结果以静态html形式交给iis,iis返回最终的响应. 不仅如此,IIS 将尝试对发出请求的用户进行身份验证,并确定通过身份验证的用户是否有权限访问被请求的文件。在处理请求的有效期内,IIS 将经历几个状态。在每个状态下,IIS 都将引发可以使用 ISAPI 筛选器以编程方式进行处理的事件.与 ISAPI 扩展一样,ISAPI 筛选器是在Web服务器上安装的非托管代码块.ISAPI扩展被设计为可以响应针对特定文件类型的请求.另外,ISAPI筛选器还包含可以对IIS引发的事件进行响应的代码.ISAPI筛选器可以截取甚至修改传入和传出的数据 而asp.net引擎可以: 在处理请求时触发事件 允许任意数量的http模块处理引发的事件,这与iis的ISAPI筛选器相似 将呈现被请求资源这项任务委托给 HTTP 处理程序,该处理程序与 IIS的ISAPI扩展相似 asp.net引擎在请求有效期内触发事件,通过信号来表示从一个状态转换到另外的状态.在asp.net引擎首次响应请求时,BeginRequest 事件将被触发,接下来触发的是AuthenticateRequest 事件(该事件在已建立用户标识时出现),还会有其他大量的事件.这些事件属于 System.Web.HttpApplication 类.asp.net提供的http模块能够处理asp.net引擎引发的事件.可以将多个http模块配置到asp.net web应用程序中.对于由asp.net引擎处理的每个请求,将初始化每个已配置的 http模块,并允许将事件处理程序绑定到处理请求期间所引发的事件.对每个请求均使用了许多内置 HTTP 模块. iis中,传入的请求最终传送到ISAPI扩展,然后ISAPI返回特定请求的数据到iis,再通过iis响应用户的请求数据.asp.net引擎使用相似的方法.初始化http模块后,asp.net引擎将确定应由哪个 http处理程序来处理请求.所有通过asp.net引擎传递的请求最终都将到达httpHandle或httpHandlerFactory(httpHandleFactory仅返回httpHandle的实例,然后使用该实例来处理请求).最终的httpHandle将返回响应,呈现被请求的资源.此响应将被发送回 IIS,然后 IIS 将响应返回给提出请求的用户 总的来说,对于来自客户端对asp.net资源请求,iis在收到后将请求调度传给aspnet_isapi.dll,然后asp.net引擎对已配置的http模块进行初始化.最后将调用正确的http处理程序,并呈现被请求的资源,将所生成的标记返回给iis,最后由iis返回到请求客户端.
对URL重写 创建自定义httpHandle,httpMoudle 在asp.net中对url进行重写,需要创建自定义的http模块或http处理程序.如何创建http模块或http处理程序,可参见创建一个最简单的 HTTP Handler.需要注意的是要实现正确接口接口的托管类:http模块实现 System.Web.IHttpModule接口,httpHandle和httpHandlerFactory分别实现System.Web.IHttpHandler接口和System.Web.IHttpHandlerFactory接口. 创建自定义的httpHandle或httpMoudle完成后,需要注册到应用程序,同时确保 HTTP 处理程序使用的扩展名已从iis映射到asp.net引擎,这样asp.net引擎才能把请求正确地路由到相应的http处理程序.为特定的web应用程序注册,需要在web.config的configuration/system.web节添加如下信息.
其中type值提供了http模块的程序集和类名称,而name值提供了友好名称,可以在 Global.asax 文件中使用此名称来引用http模块。 重写URL 有了以上的基础,现在可以创建url重写引擎,以对url进行重写处理. 除了此之外,Web.config 文件还包含重写规则:要查找的url模式,查找后替换的字符串.参见如下:
![](https://www.cnblogs.com/Images/dot.gif)
<lookFor>节点信息是由正则表达式组成,<sendTo>节点信息由匹配后替换的字符串.每个需要重写的符串均需要进行重写其规则.
使用http模块执行URL重写 在asp.net中使用http模块对url进行重写.必须决定在请求有效期内的哪个时间点上来检查url是否需要重写.为什么?因为asp.net内置的http模块使用Request的对象的属性执行任务,重写路径将改变Request对象属性的值.下面列出了这些密切相关的内置http模块及其捆绑到的事件:
HTTP 模块 | 事件 | 说明 |
FormsAuthenticationModule | AuthenticateRequest | 确定用户是否通过了窗体身份验证。如果没有,用户将被自动重定向到指定的登录页面。 |
FileAuthorizationMoudle | AuthorizeRequest | 使用 Windows 身份验证时,此 HTTP 模块将检查以确保 Microsoft® Windows® 帐户对被请求的资源具有足够的权限。 |
UrlAuthorizationModule | AuthorizeRequest | 检查以确保请求者可以访问指定的 URL。通过 Web.config 文件中的 <authorization> 和 <location> 元素来指定 URL 授权。 |
如果在BeginRequest或AuthenticateRequest事件中执行url重写,在用户访问受限资源时,被转到到登录页面去,当登陆页面提交后,用户会被重定向到重写后的页面上.此过程是:用户请求资源,asp.net引擎引发BeginRequest或AuthenticateRequest事件,url被重写.而后FormAutherticationModule将运行,将用户重定向到登陆页面.在用户成功登录后将被重定向到重写后的url页面上去.因为当FormsAuthenticationModule运行后,此url即是请求的url.同时UrlAuthorizationModule看到的将是重写后的url,如果web.config中使用了<location>元素为特定的url授权,就必须要引用重写后的url. 这是在采用form认证的情况 为了解决上述方式引起url授权和窗体认证问题,我们可以在AuthorizeRequest事件中执行url重写.那这样就会出现新的问题:文件授权无法工作.使用 Windows身份验证时,FileAuthorizationModule将检查以确保通过身份验证的用户具有访问特定请求页面的相应权限。例如用户输入的是http://site.com/a.aspx,url重定向后为http://site.com/infor.aspx?id=1,如果用户没有windows级别的访问权限,他们将会收到授权错误的消息.因为url重写在AuthenticateRequest事件中,当FileAuthorizationModule执行权限检查时,被认为请求的是a.aspx(实际上这个文件并不存在),也就绕过了文件授权检查,运行将http://site.com/infor.aspx?id=1的信息反馈给请求的用户. 何时在http模块中执行url重写,取决于要使用的身份验证的类型,不使用身份认证,则写BeginRequest、AuthenticateRequest还是AuthorizeRequest中都没关系.如果要使用form身份验证而不使用Windows身份验证,建议将url重写放在AuthorizeRequest事件处理程序中执行;如果要使用Windows身份验证,建议在BeginRequest或AuthenticateRequest事件进行过程中进行url重写.
使用http处理程序执行URL重写 要通过http处理程序执行url重写,可以创建一个httpHandlerFactory,该处理程序工厂必须实现IHttpHandlerFactory接口,此接口中包括GetHandler()方法.这个方法将检查被请求的路径,以确定是否要重写url.如果需要,它可以调用传入的HttpContext对象的 RewritePath()方法.最后,httpHandlerFactory可以返回由System.Web.UI.PageParser类的GetCompiledPageInstance()方法返回的http处理程序.