65.9K
CodeProject 正在变化。 阅读更多。
Home

新一代 URL 重写器?

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.60/5 (9投票s)

2008年4月18日

Ms-PL

7分钟阅读

viewsIcon

93425

downloadIcon

371

一个利用 IIS7 集成 ASP.NET 管道的全新高级功能的 URL 重写器/重定向器



引言

我一直很难找到一个完全满足我需求的 ASP.NET URL 重写器,所以大约一年前,在我试图遵循第三方开源代码和相关糟糕文档的过程中经历了很多挫折后,我决定自己写一个。此后,我已将此 URL 重写器/重定向器重新命名为 nUrlRewriter 版本 2。nUrlRewriter 已发布在流行的下载网站上,例如 codeplex.comcode.msdn.microsoft.com

nUrlRewriter 是一个用托管 C# 代码编写的 ASP.NET Http 模块。nUrlRewriter 会检查传入的 HTTP 请求并应用用户定义的标准,这可能会导致 HTTP 请求被重定向或重写。现有网站中的网页经常被存档或淘汰,但可能仍然存在许多指向这些网页的互联网链接。nUrlRewriter 通过提供一个易于重定向或重写此类 HTTP 请求到其他网站页面或 Web 应用程序的机制来解决这个问题。例如,一个已停产的产品网页可以重定向到一个通用的产品类别网页。nUrlRewriter 与其他重定向器/重写器不同之处在于,nUrlRewriter 还支持 IIS7 集成管道,使 nUrlRewriter 能够重定向/重写 IIS7 Web 服务器支持的任何传入 Web 应用程序 URL,包括但不限于原生 HTML 应用程序 (htm, html)、经典 ASP 应用程序 (asp)、PHP 应用程序 (php) 以及 ASP.NET (aspx) 应用程序。

重定向的传入 HTTP 请求会返回给原始浏览器,状态码为 301(永久)或 302(临时),表示请求的网页已移动到提供给浏览器的新的目标 URL。然后浏览器会为新 URL 发出新的 HTTP 请求。HTTP 状态码 301 表示 URL 已永久移动,浏览器应在新发出的 HTTP 请求中使用新 URL。HTTP 状态码 302 表示 URL 已临时移动,浏览器仅应在当前 HTTP 请求中使用新 URL。

重写的传入 HTTP 请求会被重写到 IIS 中的不同 URL 位置。由于原始浏览器不会被告知 URL 重写,因此 URL 重写发生前的浏览器地址栏将继续显示原始 URL。

nUrlRewriter 在 IIS5 和 IIS6 上同样适用。

背景

显然,IIS7 凭借全新的内部架构和新增的丰富 **远程管理和功能委派** 增强功能,开启了新一代的 Web 托管,并需要新一代的支持基础设施工具,例如 URL 重写器/重定向器。

nUrlRewriter 不仅在 IIS5 或 IIS6 环境中运行良好,而且 nUrlRewriter 还利用了新的 IIS7 集成 ASP.NET 管道,简化了原生 HTML 应用程序 (.htm, .html)、经典 ASP (.asp)、PHP 应用程序 (.php) 和 ASP.NET (.aspx) 应用程序之间的通信。

nUrlRewriter 可用于以下方面

  1. 在淘汰或存档网页时进行重定向/重写。
  2. 将友好 URL 格式重写为内部 URL 格式。
  3. 重定向到辅助文件夹位置;例如,特定语言的网站内容可能位于不同的文件夹中,或者单个 IP 地址可能托管多个网站,域名相关内容位于子文件夹中。
  4. 提供 URL 特定 robots.txt 文件。例如,如果单个 IP 地址支持多个网站,则在请求时可以返回特定网站的 robots.txt 文件。

重定向传入 HTTP 请求

Redirecting Incoming Http Requests

重写传入 HTTP 请求

Rewriting Incoming Http Requests

与 IIS 版本 5 或 6 一起使用

nUrlRewriter 以 Http Module 的形式执行,因此必须在 web.config 的 <system.web> <httpModules> 配置节中定义 nUrlRewriter,如下例所示

   1:    <system.web>
   2:      <httpModules>
   3:        <add name="nUrlRewriter"
   4:             type="nUrlRewriter.HttpModule, 
   5:                    nUrlRewriter,
   6:                    Version=2.0.0.0,
   7:                    Culture=neutral,
   8:                    PublicKeyToken=741b921e11e02781"/>      
   9:      </httpModules>
  10:    </system.web>

要配置特定的 nUrlRewriter 选项,必须声明 nUrlRewriter web.config 配置节,如下例所示

   1:    <configSections>
   2:      <section name="nUrlRewriter" 
   3:               type="nUrlRewriter.Configuration2.Configuration, 
   4:                      nUrlRewriter,
   5:                      Version=2.0.0.0,
   6:                      Culture=neutral,
   7:                      PublicKeyToken=741b921e11e02781"/>
   8:    </configSections>

一旦定义了 nUrlRewriter Http Module 并声明了 nUrlRewriter 配置节,就必须在 web.config 中定义 nUrlRewriter 特定配置节。

我目前支持两个网站;我的公司网站 - www.sanibellogic.com 和我的个人网站 - www.plippard.com。两个网站的入口点都在根目录(wwwRoot),使用同一个 IP 地址。任何未来的附加网站也将共享相同的 IP 地址。我的网站根目录根据域名进行重定向,然后在子文件夹(或实际网站子文件夹)级别应用更具体的重定向/重写逻辑。本质上,在 wwwRoot 级别,sanibellogic.com 域名被重定向到 "/SL" 子文件夹,plippard.com 域名被重定向到 "/PGL" 子文件夹。由于这些网站目前托管在 IIS6 上,因此不使用 IIS7 特定的功能。IIS7 特定的功能将在本文后面讨论。

以下示例展示了用于实现上述域名重定向的根目录 nUrlRewriter 配置节

   1:  <?xml version="1.0" encoding="utf-8" ?>
   2:  <nUrlRewriter xmlns="http://schemas.sanibellogic.com/nUrlRewriter/config/2/0/0/0"
   3:                enabled="true"
   4:                trace="false">
   5:    <urls>
   6:      <clear/>
   7:   
   8:      <add name="RuleSanibelLogic"
   9:           action="redirect"
  10:           ignoreCase="true" 
  11:           redirectType="temporary"
  12:           transformType="RegExReplace"
  13:           fromScope="absolute"
  14:           from="^http(?&lt;SSL&gt;[s]?)://(www.)?sanibellogic.com/(?&lt;WebPage&gt;(.*))$"
  15:           to="http${SSL}://www.sanibellogic.com/sl/${WebPage}" />
  16:   
  17:      <add name="RulePLippard"
  18:           action="redirect"
  19:           ignoreCase="true"
  20:           redirectType="temporary"
  21:           transformType="RegExReplace"
  22:           fromScope="absolute"
  23:           from="^http(?&lt;SSL&gt;[s]?)://(www.)?plippard.com/(?&lt;WebPage&gt;(.*))$"
  24:           to="http${SSL}://www.plippard.com/pgl/${WebPage}" />
  25:   
  26:    </urls>
  27:  </nUrlRewriter>

上述配置节示例主要检查传入的域名,将子域名缺失的情况转换为 "www.",然后根据域名是 "sanibellogic.com" 还是 "plippard.com" 将传入请求重定向到定义的 ASP.NET 应用程序子文件夹(/SL 或 /PGL)。域名之后的所有子文件夹或查询字符串内容也会附加到重定向的请求中。

一旦传入请求被拦截并重定向到正确的 ASP.NET 应用程序子文件夹,nUrlRewriter(在 /SL 或 /PGL 子文件夹的上下文中运行)将再次有机会拦截并重定向或重写新的传入请求。下面的示例显示了 nUrlRewriter 在 /SL 子文件夹的上下文中运行时使用的 ASP.NET 应用程序文件夹级别的配置节

   1:  <nUrlRewriter xmlns="http://schemas.sanibellogic.com/nUrlRewriter/config/2/0/0/0"
   2:                enabled="true"
   3:                trace="false">
   4:    
   5:    <urls>
   6:      <clear/>
   7:   
   8:      <!-- Rewrite one time DownloadMe.aspx root level DownloadMe page to new location,
   9:            Note: rewriteType="transferrequest" requires IIS7 Integrated Pipeline mode -->
  10:      <add name="RuleDownloadMe"
  11:           action="rewrite"
  12:           rewriteType="rewritePath"
  13:           ignoreCase="true"
  14:           transformType="RegExReplace"
  15:           from="~/DownloadMe.aspx(?&lt;QStrings&gt;(.*))$"
  16:           to="~/Common/S/DownloadMe.aspx${QStrings}" />
  17:   
  18:      <!-- Rewrite ECartDownload.aspx web page to new location,
  19:            Note: rewriteType="transferrequest" requires IIS7 Integrated Pipeline mode -->
  20:      <add name="RuleECartDownload"
  21:           action="rewrite"
  22:           rewriteType="rewritePath"
  23:           ignoreCase="true"
  24:           transformType="RegExReplace"
  25:           from="~/Common/ECartDownload.aspx(?&lt;QStrings&gt;(.*))$"
  26:           to="~/Common/S/ECartDownload.aspx${QStrings}" />
  27:   
  28:      <!-- Rewrite PaypalIPN web page to new location,
  29:            Note: rewriteType="transferrequest" requires IIS7 Integrated Pipeline mode -->
  30:      <add name="RulePaypalIPN"
  31:           action="rewrite"
  32:           rewriteType="rewritePath"
  33:           ignoreCase="true"
  34:           transformType="RegExReplace"
  35:           from="~/Common/PaypalIPN.aspx(?&lt;QStrings&gt;(.*))$"
  36:           to="~/Common/S/PaypalIPN.aspx${QStrings}" />
  37:   
  38:      <!-- Redirect one time Products.aspx root level Products page to new location -->
  39:      <add name="RuleProducts"
  40:           action="redirect"
  41:           ignoreCase="true"
  42:           redirectType="permanent"
  43:           transformType="RegExReplace"
  44:           from="~/Products.aspx(?&lt;QStrings&gt;(.*))$"
  45:           to="~/Common/Products.aspx${QStrings}" />
  46:   
  47:      <!-- Redirect discontinued Products.aspx DotNetNuke SSLRedirect queries -->
  48:      <add name="RuleDotNetNuke00200"
  49:           action="redirect"
  50:           ignoreCase="true"
  51:           redirectType="permanent"
  52:           transformType="RegExReplace"
  53:           from="~/Common/Products.aspx\?Cat=DotNetNuke&PLong=00200$"
  54:           to="~/Common/Products.aspx?Cat=ASP.NET&PLong=00401" />
  55:   
  56:      <!-- Redirect discontinued Products.aspx DotNetNuke SSLRedirect SDK queries -->
  57:      <add name="RuleDotNetNuke00201"
  58:           action="redirect"
  59:           ignoreCase="true"
  60:           redirectType="permanent"
  61:           transformType="RegExReplace"
  62:           from="~/Common/Products.aspx\?Cat=DotNetNuke&PLong=00201$"
  63:           to="~/Common/Products.aspx?Cat=ASP.NET&PLong=00402" />
  64:   
  65:      <!-- Redirect discontinued Products.aspx DotNetNuke SmartNews queries -->
  66:      <add name="RuleDotNetNuke00202"
  67:           action="redirect"
  68:           ignoreCase="true"
  69:           redirectType="permanent"
  70:           transformType="RegExReplace"
  71:           from="~/Common/Products.aspx\?Cat=DotNetNuke&PLong=00202$"
  72:           to="~/Common/Products.aspx?Cat=ASP.NET" />
  73:   
  74:      <!-- Redirect discontinued Products.aspx DotNetNuke SmartNews SDK queries -->
  75:      <add name="RuleDotNetNuke00203"
  76:           action="redirect"
  77:           ignoreCase="true"
  78:           redirectType="permanent"
  79:           transformType="RegExReplace"
  80:           from="~/Common/Products.aspx\?Cat=DotNetNuke&PLong=00203$"
  81:           to="~/Common/Products.aspx?Cat=ASP.NET" />
  82:   
  83:      <!-- Redirect discontinued Products.aspx DotNetNuke HttpCompressionAgent queries -->
  84:      <add name="RuleDotNetNuke00204"
  85:           action="redirect"
  86:           ignoreCase="true"
  87:           redirectType="permanent"
  88:           transformType="RegExReplace"
  89:           from="~/Common/Products.aspx\?Cat=DotNetNuke&PLong=00204$"
  90:           to="~/Common/Products.aspx?Cat=ASP.NET&PLong=00400" />
  91:   
  92:      <!-- Redirect discontinued Products.aspx DotNetNuke product category -->
  93:      <add name="RuleDotNetNuke"
  94:           action="redirect"
  95:           ignoreCase="true"
  96:           redirectType="permanent"
  97:           transformType="RegExReplace"
  98:           from="~/Common/Products.aspx\?Cat=DotNetNuke$"
  99:           to="~/Common/Products.aspx?Cat=ASP.NET" />
 100:      
 101:    </urls> 
 102:   
 103:  </nUrlRewriter>

从上述 nUrlRewriter 配置节可以看出,只需在配置节中定义所需的操作,就可以轻松扩展 nUrlRewriter,而无需更改源代码。

与 IIS 版本 7 (Windows Server 2008 和 Vista) 一起使用

发布后,我完全期望利用备受宣传和期待的 Windows Server 2008 IIS7 功能。当人们计划使用更高级的 IIS7 功能,并且 Web 应用程序被定义为在“集成 ASP.NET 管道”模式下执行时,nUrlRewriter 在 web.config 中的定义方式会略有不同。nUrlRewriter Http Module 现在定义在新的 <system.webserver> 配置节中,如下所示

   1:    <system.webServer>
   2:      <modules>
   3:        <add name="nUrlRewriter"
   4:             type="nUrlRewriter.HttpModule, 
   5:                    nUrlRewriter,
   6:                    Version=2.0.0.0,
   7:                    Culture=neutral,
   8:                    PublicKeyToken=741b921e11e02781"/>
   9:      </modules>    
  10:    </system.webServer>

nUrlRewriter 配置节继续像 IIS5/6 一样声明和定义,如下所示

   1:    <configSections>
   2:      <section name="nUrlRewriter"
   3:               type="nUrlRewriter.Configuration2.Configuration, 
   4:                      nUrlRewriter,
   5:                      Version=2.0.0.0,
   6:                      Culture=neutral,
   7:                      PublicKeyToken=741b921e11e02781"/>
   8:    </configSections>

IIS7 提供的 nUrlRewriter 配置选项之一是**能够在 IIS7 支持的任何 Web 应用程序之间重写/重定向**,例如但不限于原生 HTML 应用程序 (htm, html)、经典 ASP 应用程序 (asp)、PHP 应用程序 (php) 以及 ASP.NET (aspx) 应用程序。为了达到此目的(例如),您需要将 nUrlRewriter 配置节配置为如下所示

   1:  <nUrlRewriter xmlns="http://schemas.sanibellogic.com/nUrlRewriter/config/2/0/0/0"
   2:                              enabled="true"
   3:                              trace="false">
   4:   
   5:      <topLevelExtensions>
   6:          <clear/>
   7:          <add extension="asp" />
   8:          <add extension="aspx" />
   9:          <add extension="htm" />
  10:          <add extension="html" />
  11:          <add extension="php" />
  12:      </topLevelExtensions>
  13:   
  14:      <urls>
  15:          <clear/>
  16:   
  17:          <!-- Redirect WordPress blog URL, which was a sub-folder within an ASP.NET App
  18:                      to new ASP.NET BlogEngine.Net sub-folder -->
  19:          <add name="RuleBlog"
  20:                   action="redirect"
  21:                   from="~/support/wpblog/(.+)"
  22:                   to="~/support/beblog/" />
  23:      </urls>
  24:   
  25:  </nUrlRewriter>

请注意,topLevelExtensions 标记定义了此示例中 PHP 应用程序可见性所需的候选网页扩展。

在 IIS7 中,nUrlRewriter 的另一个常见用途是**支持多个 robots.txt 文件**。robots.txt 文件通常需要放在网站的根目录下。以下 nUrlRewriter 配置节说明了如何将对根目录 robots.txt 文件的 Web 请求重写到子文件夹中的 robots.txt,从而使搜索引擎看不到其子文件夹位置。to 属性**必须**转换为以 "~/" 开头的相对 URL 位置,因为 *System.Web.HttpServerUtility.TransferRequest* 和 *System.Web.HttpContext.RewritePath* 方法都需要相对 URL 路径。请注意,"txt" 扩展也必须包含在 topLevelExtensions 集合中。

   1:    <nUrlRewriter xmlns="http://schemas.sanibellogic.com/nUrlRewriter/config/2/0/0/0"
   2:                  enabled="true"
   3:                  trace="false">
   4:   
   5:          <topLevelExtensions>
   6:              <clear/>
   7:                  <add extension="asp" />
   8:                  <add extension="aspx" />
   9:                  <add extension="htm" />
  10:                  <add extension="html" />
  11:                  <add extension="php" />
  12:                  <add extension="txt" />
  13:   
  14:          </topLevelExtensions>
  15:          
  16:          <urls>
  17:              <clear/>
  18:   
  19:              <!-- Based on incoming domain of SanibelLogic.com, rewrite to a -->
  20:              <!-- sub-folder location for the robots.txt file -->
  21:              <add name="RuleSanibelLogicRobots"
  22:                      action="rewrite"
  23:                      rewriteType="transferRequest"
  24:                      fromScope="absolute"
  25:                      from="^http(?&lt;SSL&gt;[s]?)://(www.)?sanibellogic.com/(?&lt;robotsFile&gt;(robots.txt))$"
  26:                      to="~/SL/$(robotsFile)" />
  27:   
  28:              <!-- Based on incoming domain of PLippard.com, rewrite to a -->
  29:              <!-- sub-folder location for the robots.txt file -->
  30:              <add name="RulePLippardRobots"
  31:                      action="rewrite"
  32:                      rewriteType="transferRequest"
  33:                      fromScope="absolute"
  34:                      from="^http(?&lt;SSL&gt;[s]?)://(www.)?plippard.com/(?&lt;robotsFile&gt;(robots.txt))$"
  35:                      to="~/PGL/$(robotsFile)" />
  36:   
  37:          </urls>
  38:    </nUrlRewriter>

URL 重写/重定向 Web 组件对于有效管理多个网站以及单个网站至关重要。nUrlRewriter 利用了新的高级 IIS7 集成 ASP.NET 管道功能,以确保所有 Web 应用程序(包括但不限于原生 HTML 应用程序 (htm, html)、经典 ASP 应用程序 (asp)、PHP 应用程序 (php) 和 ASP.NET 应用程序 (aspx))得到有效集成。nUrlRewriter 还利用正则表达式和灵活的配置设计,确保易于扩展而无需更改源代码。nUrlRewriter 的 .chm 帮助文件形式的文档可与 VS.NET 2008 源代码项目一起下载。

历史

2008 年 4 月 18 日 - 首次发布(尽管我已在生产环境中使用此名称一年)

© . All rights reserved.