返回页首 请求到达 iis 时将会发生什么情况 在正式研究 url 如何实现重写之前,应首先了解 microsoft® internet information services (iis) 如何处理传入请求,这一点非常重要。当请求到达 iis web 服务器时,iis 检查被请求文件的扩展名以确定如何处理该请求。iis 可以自行处理请求(如 html 页面、图像以及其他静态内容),或者将请求路由到 isapi 扩展。(isapi 扩展是一个处理传入 web 请求的非托管编译类。其任务是生成被请求资源的内容。)
例如,当传入针对 info.asp 网页的请求时,iis 会将此消息路由到 asp.dll isapi 扩展。然后,该 isapi 扩展将加载被请求的 asp 页面,执行该页面,并将所呈现的 html 返回给 iis,然后,iis 将该 html 发送回请求客户端。对于 asp.net 页面,iis 会将此消息路由到 aspnet_isapi.dll isapi 扩展。然后,aspnet_isapi.dll isapi 扩展将处理操作传递给托管的 asp.net 辅助进程,该辅助程序将处理请求,并返回 asp.net 网页的呈现 html。
您可以自定义 iis,以指定扩展名与 isapi 扩展的映射关系。图 1 显示了 internet information services 管理工具的“应用程序配置”对话框。请注意,与 asp.net 有关的扩展名(.aspx、ascx、config、asmx、rem、cs、vb 及其他)均已映射到 aspnet_isapi.dll isapi 扩展。
图 1. 已配置的文件扩展名映射
讨论 iis 如何管理传入请求稍稍超出了本文范围。但是可以在 michele leroux bustamante 的文章 inside iis and asp.net 中找到对此内容的深入讨论。asp.net 引擎仅处理那些扩展名已明确映射至 iis 中的 aspnet_isapi.dll 的传入 web 请求,了解这一点非常重要。
虽然 isapi 筛选器可用于执行 url 重写,但本文将讨论如何使用 asp.net 实现 url 重写。不过,我们将对使用 isapi 筛选器与使用 asp.net 中的技术实现 url 重写进行权衡。
请求进入 asp.net 引擎时将会发生什么情况 在 asp.net 之前,需要使用 isapi 筛选器来实现 iis web 服务器上的 url 重写。由于 asp.net 引擎与 iis 非常相似,因此可以使用 asp.net 进行 url 重写。存在相似之处的原因在于 asp.net 引擎可以实现以下功能:
asp.net 包括许多内置的 http 处理程序。例如,pagehandlerfactory 用于呈现 asp.net 网页。webservicehandlerfactory 用于呈现 asp.net web 服务的响应 soap 信封。tracehandler 将向 trace.axd 呈现请求的 html 标记。
public abstract class basemodulerewriter : ihttpmodule { public virtual void init(httpapplication app) { // 警告!此代码不适用于 windows 身份验证! // 如果使用 windows 身份验证, // 请改为 app.beginrequest app.authorizerequest += new eventhandler(this.basemodulerewriter_authorizerequest); }
注意:url 重写引擎在 <lookfor> 元素中需要使用正则表达式模式。如果您对正则表达式不熟悉,可以阅读我在早些时候编写的一篇文章 an introduction to regular expressions。另外,还有一个很好的网站:regexlib.com,在那里您可以获取有关常用正则表达式的帮助信息,还可以共享您自己的自定义正则表达式。
构建必备的目录结构 当请求 /2004/03/19.aspx 时,iis 将通知 .aspx 扩展,并将请求路由到 asp.net 引擎。请求在 asp.net 引擎的管道中移动时,url 将被重写为 showblogcontent.aspx?year=2004&month=03&day=19,并且访问者会看到 2004 年 3 月 19 日的 blog 条目。但是当用户浏览到 /2004/03/ 时将会发生什么情况呢?除非有一个 /2004/03/ 目录,否则 iis 将返回一个 404 错误。此外,此目录中还需要具有 default.aspx 页面,以便可以将请求传递给 asp.net 引擎。
很显然,添加这样一个目录结构可能是一件很痛苦的事情。解决此问题的方法是使所有传入的 iis 请求都映射到 asp.net 引擎。通过这种方法,即使访问 url /2004/03/,iis 也会如实地将请求传递给 asp.net 引擎(即使并不存在 /2004/03/ 目录)。但是,使用这种方法将使 asp.net 引擎负责处理到达 web 服务器的所有类型的传入请求,包括图像、css 文件、外部 javascript 文件、macromedia flash 文件,等等。
对处理所有文件类型的全面讨论远远超出了本文的范围。有关使用此技术的 asp.net web 应用程序的示例,请参阅 .text,一个开放源 blog 引擎。.text 可以配置为将所有请求均映射到 asp.net 引擎。它可以使用自定义 http 处理程序来处理生成所有文件类型的问题,自定义 http 处理程序了解如何生成典型的静态文件类型(图像、css 文件,等等)。
返回页首 结论 在本文中,我们讨论了如何在 asp.net 级别通过 httpcontext 类的 rewriteurl() 方法来执行 url 重写。正如我们所看到的,rewriteurl() 更新了特定的 httpcontext's request 属性,从而更新了被请求的文件和路径。最终结果是,从用户角度来看,他们要访问某个特定的 url,但从 web 服务器端来看,被请求的却是另一个 url。
当然,如果执行 asp.net 级别的重写,则仅当已成功地将请求从 iis 传递给 asp.net 引擎后才会发生 url 重写。实际上,只有用户请求带 .aspx 扩展名的页面时才会出现这种情况。但是,如果您要使用户可以进入实际并不存在的 url,但又希望重写到现有的 asp.net 页面,则必须创建虚拟目录和 default.aspx 页面,或者对 iis 进行配置,以使所有传入请求一律被路由到 asp.net 引擎。