为 URL 重写模块创建出站规则

作者:Ruslan Yakushev

本文档部分适用于 IIS 7 的 URL 重写模块版本 2.0

本演练将指导你创建并测试 URL 重写模块 2.0 的出站重写规则。

先决条件

本演练要求满足以下先决条件:

  1. 启用了 ASP.NET 角色服务的 IIS 7 或更高版本;
  2. 已安装 URL 重写模块 2.0 RC 版本。

设置测试网页

为了演示 URL 重写模块 2 的工作原理,你将使用一个简单的 ASP.NET 页。 此页读取 Web 服务器变量并在浏览器中显示其值。 它还使用服务器变量生成超链接,然后将该链接放入响应 HTML 中。

创建测试页

  1. 在以下文件夹中创建一个名为 article.aspx 的文件:

    %SystemDrive%\inetpub\wwwroot\
    
  2. 复制以下 ASP.NET 标记,将其粘贴到文件中,并保存该文件:

    <%@ Page Language="C#" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>URL Rewrite Module v2 Test</title>
    </head>
    <body>
        <h1>URL Rewrite Module v2 Test Page</h1>
        <h2>Inbound URL Rewriting</h2>
        <table>
            <tr>
                <th>Server Variable</th>
                <th>Value</th>
            </tr>
            <tr>
                <td>Original URL: </td>
                <td><%= Request.ServerVariables["UNENCODED_URL"] %></td>
            </tr>
            <tr>
                <td>Final URL: </td>
                <td><%= Request.ServerVariables["SCRIPT_NAME"] + "?" + Request.ServerVariables["QUERY_STRING"] %></td>
            </tr>
        </table>
        <h2>Outbound URL Rewriting</h2>
            <a href="<%= Request.ServerVariables["SCRIPT_NAME"] + "?" + Request.ServerVariables["QUERY_STRING"] %>">Here</a> is the link to this article.
    </body>
    </html>
    
  3. 打开 Web 浏览器并请求以下 URL,以确保页面正确呈现:

    http://localhost/article.aspx
    

添加入站重写规则

下一步是添加一个规则,用于重写采用以下格式的 URL:

http://localhost/article/342/some-article-title

这些 URL 将重写为采用如下格式:

http://localhost/article.aspx?id=342&title=some-article-title

若要添加入站重写规则,请执行以下操作:

  1. 打开位于以下位置的 web.config 文件:

    %SystemDrive%\inetpub\wwwroot\
    
  2. /configuration/system.webServer 元素下添加以下内容,然后保存文件:

    <rewrite>
      <rules>
        <rule name="Rewrite to article.aspx">
          <match url="^article/([0-9]+)/([_0-9a-z-]+)" />
          <action type="Rewrite" url="article.aspx?id={R:1}&amp;title={R:2}" />
        </rule>
      </rules>
    </rewrite>
    

有关创建入站重写规则的详细信息,请参阅为 URL 重写模块创建重写规则

测试入站重写规则

现在可以测试入站重写规则是否按设计运行。

若要测试入站重写规则,请执行以下操作:

打开 Web 浏览器并请求以下 URL:

http://localhost/article/342/some-article-title

如果重写规则正常工作,你将从服务器收到如下所示的响应:

Screenshot of the Final U R L after hovering over the link in the U R L Rewrite Module Test Page using a web browser.

可以看到,由于入站规则,可以使用简单且用户友好的 URL 结构来访问此网页。 但是,如果用户单击 HTML 页中的超链接,Web 浏览器将使用带有查询字符串参数的 URL。 出于多种原因,这并不是理想方式:

  1. 网站访问者会看到你想要使用 URL 重写规则隐藏的内部 URL 结构。
  2. 同一页可以通过多个 URL 访问,这对于搜索引擎优化而言并不理想。

解决此问题的最直接方法是修改 HTML 页以使用简单的链接结构。 但是,在许多情况下做不到这一点。 例如,如果已有一个复杂的传统 Web 应用程序或无法修改的 Web 应用程序,则修复应用程序中所有 URL 链接的任务可能非常耗时,或者根本不可行。

这时,出站 URL 重写便可以发挥作用。 出站 URL 重写可以即时修复应用程序生成的响应中的链接。

创建出站重写规则

现在,你将创建一个出站重写规则来更改 HTML 响应中的 URL。 该规则将更改采用以下格式的 URL:

http://localhost/article.aspx?id=342&title=some-article-title

这些 URL 将重写为以下内容:

http://localhost/article/342/some-article-title

你将使用 IIS 管理器中的“URL 重写”用户界面创建出站规则。

若要创建出站规则,请执行以下操作:

  1. 打开 IIS 管理器
  2. 选择“默认网站”
  3. 在功能视图中,选择“URL 重写”
    Screenshot of U R L Rewrite selected in the Default Web Site Home pane.
  4. 在右侧的操作窗格中,单击“添加规则...”。 在“添加规则”对话框中,选择“出站规则”类别下的“空白规则”,然后单击“确定”。
    Screenshot of selecting a Blank rule template under Outbound rules in the Add Rules dialog.

现在必须定义实际的出站规则。 在 URL 重写模块 2.0 中,出站重写规则是通过指定以下信息来定义的:

  • 规则名称。
  • 用于控制是否应将此规则应用于响应的可选前提条件。
  • 用于匹配响应中的字符串的模式。
  • 一组可选条件。
  • 当模式匹配并且所有条件检查都成功时要执行的操作。

为规则命名

在“名称”文本框中输入用于唯一标识该规则的名称,例如:“重写为干净 URL”。

定义前提条件

前提条件用于评估是否应对响应执行出站规则评估。 例如,如果修改 HTML 内容的规则,则仅应根据此规则评估内容类型标头设置为“text/html”的 HTTP 响应。 出站规则评估和内容重写是 CPU 密集型操作,可能会对 Web 应用程序的性能产生负面影响。 因此,在应用出站规则时,请使用前提条件来缩小范围。

由于创建的规则应仅应用于 HTML 响应,因此需要定义一个前提条件来检查 HTTP 响应头 content-type 是否等于“text/html”。

若要定义前提条件,请执行以下操作:

  1. 在“前提条件”列表中,选择“创建新的前提条件”<>。

  2. 随即你会转到“前提条件编辑器”对话框,需要在其中定义前提条件。 如下所述指定前提条件设置:

    • 名称:“IsHTML”

    • 使用:“正则表达式”

    • 单击“添加”以显示“添加条件”对话框。 在此对话框中,指定:

      • 条件输入:“{RESPONSE_CONTENT_TYPE}”

      • 检查输入字符串:“匹配模式”

      • 模式:“^text/html”

        Screenshot of adding a new pre-condition with the specified settings.

  3. 单击“确定”保存前提条件并返回到“编辑规则”页。

定义匹配范围

出站重写规则可以对 HTTP 标头的内容或响应正文内容进行操作。 该规则需要替换响应内容中的链接,因此请在“匹配范围”下拉列表中选择“响应”。

定义标记筛选器

标记筛选器用于将模式匹配范围限定为仅与特定 HTML 元素匹配,而不是根据规则的模式评估整个响应。 模式匹配是一项非常消耗 CPU 资源的操作,如果根据模式评估整个响应,可能会显著减慢 Web 应用程序的响应速度。 标记筛选器允许指定仅在某些 HTML 标记的内容中应用模式匹配,从而显著减少必须根据正则表达式模式进行评估的数据量。

若要定义标记筛选器,请展开下拉列表“匹配以下范围的内容:”,然后选中复选框“A (href 属性)”

这会将规则设置为仅将模式应用于超链接的 href 属性值,如以下示例所示:

<a href="this string will be used for pattern matching">Some link</a>

定义模式

在“模式”文本框中输入以下字符串:

^/article\.aspx\?id=([0-9]+)(?:&|&amp;)title=([_0-9a-z-]+)$

此字符串是一个正则表达式,指定模式将匹配任何满足以下条件的 URL 字符串:

  • 以字符序列“/article.aspx?”开头。
  • 包含具有数值的第一个查询字符串参数。
  • 包含具有字母数字值的第二个查询字符串参数。

请注意,正则表达式的某些部分包含在括号中。 这些括号创建一个捕获组,稍后可以使用反向引用在规则中引用该捕获组。 此外,在大多数情况下,“&”符号是在响应中进行 HTML 编码的,因此正则表达式模式需要考虑到这一点。

定义操作

在“操作”组框中选择“重写”操作类型。 在“值”文本框中,输入以下字符串:

/article/{R:1}/{R:2}

此字符串指定链接地址应重写为的新值。 请注意,对于查询字符串参数值,表达式使用了 {R:1} 和 {R:2},它们是对使用括号在规则模式中定义的捕获组的反向引用。

保留所有其他设置的默认值。 “编辑规则”属性页将如下所示:

Screenshot before applying the new Outbound Rewrite Rule with the Is H T M L Pre-condition

单击右侧的“应用”操作保存规则。

查看配置文件中的重写规则

重写规则存储在 aplicationHost.config 文件或 web.config 文件中。 若要检查我们刚刚创建的规则的配置,请打开 web.config 文件,该文件位于

%SystemDrive%\inetput\wwwroot\

在此文件中,你将看到包含所有规则定义的 <rewrite> 部分,如以下示例所示:

<rewrite>
 <rules>
  <rule name="Rewrite to article.aspx">
   <match url="^article/([0-9]+)/([_0-9a-z-]+)" />
   <action type="Rewrite" url="article.aspx?id={R:1}&amp;title={R:2}" />
  </rule>
 </rules>
 <outboundRules>
  <rule name="Rewrite to clean URL" preCondition="IsHTML">
   <match filterByTags="A" pattern="^/article\.aspx\?id=([0-9]+)(?:&amp;|&amp;amp;)title=([_0-9a-z-]+)$" />
   <action type="Rewrite" value="/article/{R:1}/{R:2}" />
  </rule>
  <preConditions>
   <preCondition name="IsHTML">
    <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
   </preCondition>
  </preConditions>
 </outboundRules>
</rewrite>

测试规则

现在可以测试规则是否正确重写 URL。 打开 Web 浏览器并请求以下 URL:

http://localhost/article/342/some-article-title

应会看到出站重写规则已更改 HTML 响应中的链接:

Screenshot of the new U R L after hovering over the link in the U R L Rewrite Module Test Page using a web browser.

现在,如果站点访问者单击此链接,将使用干净的 URL 格式,并且不会显示此页使用的内部 URL 表示形式。

总结

在本演练中,你已了解如何使用 IIS 管理器或通过手动编辑 web.config 文件在 URL 重写模块 2.0 中配置出站重写规则。 本演练中创建的规则演示了 URL 重写模块 2.0 的一些重要功能,例如出站重写、前提条件和标记筛选器。