引言
让我们花点时间来看一下网站上的一些 URL您是否发现一些类似于 x?EmpID=&type=summary 的 URL?或者您可能将一系列网页从一个目录或网站移动到另一个目录或网站结果导致已将旧 URL 用作书签的访问者断开链接在本文中我们将了解如何通过将 x?EmpID=&type=summary 替换为类似于 的网址使用 URL 重写将那些冗长的 URL 缩写为富有意义且容易记忆的 URL我们还将了解如何将 URL 重写用于创建智能 错误
URL 重写是截取传入 Web 请求并自动将请求重定向到其他资源的过程执行 URL 重写时通常会检查被请求的 URL并基于 URL 的值将请求重定向到其他 URL例如在进行网站重组而将 /people/ 目录下的所有网页移动到 /info/employees/ 目录中时您可能希望使用 URL 重写来检查 Web 请求是否指向了 /people/ 目录中的文件如果请求指向 /people/ 目录中的文件您可能希望自动将请求重定向到 /info/employees/ 目录中的同一文件
使用传统的 ASP应用 URL 重写的唯一方法是编写 ISAPI 筛选器或者购买提供 URL 重写功能的第三方产品但是使用 Microsoft® ASPNET您可以通过很多方法来轻松地创建您自己的 URL 重写软件本文讨论了可供 ASPNET 开发人员实现 URL 重写的各种技术然后讨论了 URL 重写的一些实际使用情况在深入讨论 URL 重写的技术细节之前让我们先看一些可以使用 URL 重写的日常情景
URL 重写的常见用法
创建数据驱动的 ASPNET 网站时通常会产生一个单个的网页该网页基于查询字符串参数显示数据库数据的子集例如在设计电子商务站点时您的任务之一便是允许用户浏览待售产品为此您可以创建一个名为 displayCategoryaspx 的页面该页面将显示给定类别的产品可以通过查询字符串参数来指定要查看的该类别的产品也就是说如果用户要浏览待售的 Widget 产品并且所有 Widget 产品的 CategoryID 均为 则用户可以访问以下网址x?CategoryID=
创建具有此类 URL 的网站有两点不足首先从最终用户的角度考虑URL x?CategoryID= 比较杂乱可用性专家 Jakob Neilsen建议遵循以下标准来选择 URL
; 简短
; 易于键入
; 可以看出站点的结构
; 可删节允许用户通过删除 URL 的组成部分来浏览站点
我还要增加一条标准即URL 应该便于记忆URL x?CategoryID= 不符合 Neilsen 的任何标准也不容易记住要求用户键入查询字符串值将使 URL 的键入变得非常困难并且只有了解查询字符串参数的用途及其名称/值对结构的富有经验的 Web 开发人员才能够对 URL 进行删节
较好的方法是允许使用切合实际且容易记忆的 URL如 只要看一眼 URL您便可以推断出将要显示的内容 有关 Widget 的信息此 URL 也很容易记住和共享我可以告诉我的同事请查看 /products/Widgets她可能无需再次问我 URL 是什么即可打开该页面(尝试一下您只需说出 页面即可!)此 URL 还将显示出来并且应该是可删节的也就是说如果用户删去 URL 的末端键入 他们应该看到所有产品的列表或者至少应该看到他们可以查看的所有类别的产品列表
注意要获得可删节URL 的最好示例可考虑使用由许多 blog 引擎生成的 URL要查看 年 月 日的帖子用户可以访问诸如 的 URL如果该 URL 被删节为 用户将看到 年 月的所有帖子将该 URL 进一步删节为 将显示 年的所有帖子
除了简化 URL 之外URL 重写还经常用于处理网站重组以免导致大量链接断开或书签过期
请求到达 IIS 时将会发生什么情况
在正式研究 URL 如何实现重写之前应首先了解 Microsoft® Internet Information Services (IIS) 如何处理传入请求这一点非常重要当请求到达 IIS Web 服务器时IIS 检查被请求文件的扩展名以确定如何处理该请求IIS 可以自行处理请求(如 HTML 页面图像以及其他静态内容)或者将请求路由到 ISAPI 扩展(ISAPI 扩展是一个处理传入 Web 请求的非托管编译类其任务是生成被请求资源的内容)
例如当传入针对 Infoasp 网页的请求时IIS 会将此消息路由到 aspdll ISAPI 扩展然后该 ISAPI 扩展将加载被请求的 ASP 页面执行该页面并将所呈现的 HTML 返回给 IIS然后IIS 将该 HTML 发送回请求客户端对于 ASPNET 页面IIS 会将此消息路由到 aspnet_isapidll ISAPI 扩展然后aspnet_isapidll ISAPI 扩展将处理操作传递给托管的 ASPNET 辅助进程该辅助程序将处理请求并返回 ASPNET 网页的呈现 HTML
您可以自定义 IIS以指定扩展名与 ISAPI 扩展的映射关系图 显示了 Internet Information Services 管理工具的应用程序配置对话框请注意与 ASPNET 有关的扩展名(aspxascxconfigasmxremcsvb 及其他)均已映射到 aspnet_isapidll ISAPI 扩展
图 已配置的文件扩展名映射讨论 IIS 如何管理传入请求稍稍超出了本文范围但是可以在 Michele Leroux Bustamante 的文章 Inside IIS and ASPNET 中找到对此内容的深入讨论ASPNET 引擎仅处理那些扩展名已明确映射至 IIS 中的 aspnet_isapidll 的传入 Web 请求了解这一点非常重要
<b>使用 ISAPI 筛选器检查请求</b>
IIS 除了可以将传入 Web 请求的文件扩展名映射到相应的 ISAPI 扩展之外还将执行许多其他任务例如IIS 将尝试对发出请求的用户进行身份验证并确定通过身份验证的用户是否有权限访问被请求的文件在处理请求的有效期内IIS 将经历几个状态在每个状态下IIS 都将引发可以使用 ISAPI 筛选器以编程方式进行处理的事件
与 ISAPI 扩展一样ISAPI 筛选器是在 Web 服务器上安装的非托管代码块ISAPI 扩展被设计为可以响应针对特定文件类型的请求另一方面ISAPI 筛选器还包含可以对 IIS 引发的事件进行响应的代码ISAPI 筛选器可以截取甚至修改传入和传出的数据ISAPI 筛选器可以应用于很多方面包括
; 身份验证和授权
; 记录和监视
; HTTP 压缩
; URL 重写
虽然 ISAPI 筛选器可用于执行 URL 重写但本文将讨论如何使用 ASPNET 实现 URL 重写不过我们将对使用 ISAPI 筛选器与使用 ASPNET 中的技术实现 URL 重写进行权衡
请求进入 ASPNET 引擎时将会发生什么情况
在 ASPNET 之前需要使用 ISAPI 筛选器来实现 IIS Web 服务器上的 URL 重写由于 ASPNET 引擎与 IIS 非常相似因此可以使用 ASPNET 进行 URL 重写存在相似之处的原因在于 ASPNET 引擎可以实现以下功能
; 在处理请求时可以引发事件
; 允许任意数量的 HTTP 模块处理所引发的事件这与 IIS 的 ISAPI 筛选器相似
; 将呈现被请求资源这项任务委托给 HTTP 处理程序该处理程序与 IIS 的 ISAPI 扩展相似
与 IIS 一样ASPNET 引擎在请求的有效期内将会触发事件通过发信号来表示其处理过程从一个状态改变为了另一个状态例如当 ASPNET 引擎首次响应请求时BeginRequest 事件将被触发接下来触发的是 AuthenticateRequest 事件该事件在已建立用户标识时出现(此外还有大量的其他事件AuthorizeRequestResolveRequestCache 和 EndRequest等等这些事件属于 SystemWebHttpApplication 类有关详细信息请参阅位于以下网址的技术文档HttpApplication Class Overview)
正如上一部分所讨论的可以创建 ISAPI 筛选器以响应 IIS 引发的事件同样ASPNET 提供了 HTTP 模块该模块可以响应由 ASPNET 引擎引发的事件可以将 ASPNET Web 应用程序配置为具有多个 HTTP 模块对于由 ASPNET 引擎处理的每个请求将初始化每个已配置的 HTTP 模块并允许将事件处理程序绑定到处理请求期间所引发的事件请注意对每个请求均使用了许多内置 HTTP 模块其中的一个内置 HTTP 模块是 FormsAuthenticationModule该模块首先检查是否使用了窗体身份验证如果使用将检查是否对用户进行了身份验证如果没有使用会自动将用户重定向到指定的登录页面
如上所述通过使用 IIS传入请求将最终发送给 ISAPI 扩展而 ISAPI 扩展的任务是返回特定请求的数据例如在请求传统的 ASP 网页时IIS 将请求传递给 aspdll ISAPI 扩展该扩展的任务是返回被请求的 ASP 页面的 HTML 标记ASPNET 引擎使用相似的方法初始化 HTTP 模块后ASPNET 引擎的下一项任务是确定应由哪个 HTTP 处理程序来处理请求
所有通过 ASPNET 引擎传递的请求最终都将到达 HTTP 处理