在 URL 重写模块中使用重写映射
本演练介绍 URL 重写模块中重写映射的概念,并指导你创建使用重写映射的重写规则。 在本演练中,你将创建两个重写映射:一个重写映射由执行 url 重写的规则使用,另一个重写映射由执行重定向到不同域的规则使用。
背景
重写映射是名称和值对的任意集合,可在重写规则中用于在重写期间生成替换 URL。 当你有一大套重写规则时,重写映射特别有用,所有这些规则都使用静态字符串(例如没有使用模式匹配时)。 在这种情况下,可以将输入 URL 和替换 URL 之间的所有映射(作为键和值)放入重写映射中,而不要定义大量简单的重写规则。 然后,在根据输入 URL 查找替换 URL 时,将有一个引用此重写映射的重写规则。
先决条件
本演练要求满足以下先决条件:
- 启用了 ASP.NET 角色服务的 IIS 7.0 或更高版本
- 已安装 URL 重写 Go Live 版本
设置测试网页
为了演示重写映射功能,我们将使用一个简单的测试 asp.net 页。 此页读取 Web 服务器变量并在浏览器中输出其值。
复制以下 ASP.NET 代码,并将其放入名为“article.aspx”的文件中的 %SystemDrive%\inetpub\wwwroot\
文件夹中:
<%@ 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 Test</title>
</head>
<body>
<h1>URL Rewrite Module Test Page</h1>
<table>
<tr>
<th>Server Variable</th>
<th>Value</th>
</tr>
<tr>
<td>Original URL: </td>
<td><%= Request.ServerVariables["HTTP_X_ORIGINAL_URL"] %></td>
</tr>
<tr>
<td>Final URL: </td>
<td><%= Request.ServerVariables["SCRIPT_NAME"] + "?" + Request.ServerVariables["QUERY_STRING"] %></td>
</tr>
</table>
</body>
</html>
复制此文件后,浏览到 http://localhost/article.aspx
并检查系统是否已在浏览器中正确呈现页面。
创建重写映射
首先,我们创建一个重写映射和重写规则,用于根据原始 URL 和重写 URL 之间的一组静态映射来执行 URL 重写。 若要创建重写映射,请执行以下步骤:
转到 IIS 管理器
选择“默认网站”
在新建的重写映射页上的右侧“操作”窗格中,单击“添加映射条目...”,然后分别在“原始值:”和“新值:”文本框中,输入“/article”和“/article.aspx?id=1&title=some-title”。 原始值指定我们要重写的源 URL 路径;新值指定我们要重写为的 URL 路径。
重复步骤 6 将以下映射添加到重写映射中:
原始值: 新值: /some-title /article.aspx?id=1&title=some-title /post/some-title.html /article.aspx?id=1&title=some-title
现在打开网站的 web.config 文件(如果使用默认网站,可以在 %SystemDrive%\inetpub\wwwroot
找到 web.config)。 应会看到以下部分:
<rewrite>
<rewriteMaps>
<rewriteMap name="StaticRewrites" defaultValue="">
<add key="/article1" value="/article.aspx?id=1&title=some-title" />
<add key="/some-title" value="/article.aspx?id=1&title=some-title" />
<add key="/post/some-title.html" value="/article.aspx?id=1&title=some-title" />
</rewriteMap>
</rewriteMaps>
</rewrite>
此重写映射名为“StaticRewrites”,用于将传入 URL(定义为重写映射中的键)重写为其内部表示形式(定义为值)。 defaultValue 属性指定在映射中尚未定义传入 URL 时要使用的值。 在本例中,将返回一个空字符串。
请注意,键及其与值的关系没有明显的共同模式。 这意味着无法使用正则表达式或通配符来定义 URL 转换逻辑。 此外,这意味着如果没有使用重写映射,我们将不得不创建三个重写规则。 使用重写映射只能创建一个重写规则。 下一部分将介绍如何创建使用此重写映射的重写规则。
从重写规则引用重写映射
若要创建使用重写映射的重写规则,请将以下 XML 代码复制并粘贴到网站的 web.config 文件的 <rewrite>
部分:
<rules>
<rule name="Rewrite Rule">
<match url=".*" />
<conditions>
<add input="{StaticRewrites:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Rewrite" url="{C:1}" />
</rule>
</rules>
让我们仔细查看每个规则元素以了解其作用:
<match url=".*" />
- 此元素告知 URL 重写模块匹配任何传入 URL(通过使用正则表达式特殊字符“.”)
<add input="{StaticRewrites:{REQUEST\_URI}}" pattern="(.+)">
- 此条件检查从重写映射 StaticRewrites 返回的值是否不是空字符串。 为了执行此项检查,服务器变量 REQUEST_URI 的值将作为参数传递给重写映射。 如果重写映射包含带有键的条目(即与 REQUEST_URI 相同),则将返回与该键对应的值。 正则表达式模式将仅匹配非空字符串,因此如果从映射返回空字符串,则条件将计算为 false,因此不会执行重写。 如果返回非空字符串,则由于模式中使用了括号,该字符串将在反向引用中被捕获。
<action type="Rewrite" url="{C:1}" />
- 此元素指定 URL 重写模块需要使用从重写映射中提取的新 URL 字符串来重写当前 URL 字符串。 请注意,url 属性引用了条件反向引用 {C:1},该条件反向引用是在条件中的模式匹配时设置的。
测试重写规则
若要测试使用“StaticRewrites”映射的重写规则,请打开 Web 浏览器并请求以下任意 URL:
http://localhost/article1
http://localhost/some-title
http://localhost/post/some-title.html
上述任何一个 URL 都应该导致 URL 根据重写映射中定义的映射进行重写。 结果应如下所示:
使用重写映射进行重定向
现在我们将创建另一个重写映射,用于定义源 URL 和重定向 URL 之间的静态映射。 若要创建重写映射,请按照创建重写映射部分中所述的相同步骤进行操作,但需将重写映射命名为“StaticRedirects”并使用以下映射条目值:
原始值: | 新值: |
---|---|
/old-article.aspx?id=1 | /article.aspx?id=1 |
/posts/default.aspx?id=1 | /article.aspx?id=1 |
/old-title.html | /article.aspx?id=1 |
网站的 web.config 文件现在应包含以下两个重写映射:
<rewriteMaps>
<rewriteMap name="StaticRewrites">
<add key="/article1" value="/article.aspx?id=1&title=some-title" />
<add key="/some-title" value="/article.aspx?id=1&title=some-title" />
<add key="/post/some-title.html" value="/article.aspx?id=1&title=some-title" />
</rewriteMap>
<rewriteMap name="StaticRedirects">
<add key="/old-article.aspx?id=1" value="/article.aspx?id=1" />
<add key="/posts/default.aspx?id=1" value="/article.aspx?id=1" />
<add key="/old-title.html" value="/article.aspx?id=1" />
</rewriteMap>
</rewriteMaps>
若要创建使用 StaticRedirects 重写映射的规则,请将以下规则定义复制并粘贴到网站的 web.config 文件中:
<rules>
<rule name="Redirect Rule" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{StaticRedirects:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Redirect" url="http://localhost{C:1}" appendQueryString="False" redirectType="Permanent" />
</rule>
</rules>
同样,让我们仔细查看每个规则元素以了解其作用:
<match url=".*" />
- 此元素告知 URL 重写模块匹配任何传入 URL(通过使用正则表达式特殊字符“.”)
<add input="{StaticRedirects:{REQUEST\_URI}}" pattern="(.+)">
- 此条件检查从重写映射 StaticRedirects 返回的值是否不是空字符串。 为了执行此项检查,服务器变量 REQUEST_URI 的值将作为参数传递给重写映射。 如果重写映射包含带有键的条目(即与 REQUEST_URI 相同),则将返回与该键对应的值。 正则表达式模式将仅匹配非空字符串,因此如果从映射返回空字符串,则条件将计算为 false,因此不会执行重写。 如果返回非空字符串,则由于模式中使用了括号,该字符串将在反向引用中被捕获。
<action type="Redirect" url="http://localhost{C:1}" appendQueryString="False" redirectType="Permanent" />
- 此元素指定 URL 重写模块需要将 Web 客户端重定向到一个新 URL,该 URL 是通过连接新域名(在本例中为简单起见,它是同一个域)和 StaticRedirects 映射返回的重定向 URL 路径而构造的。
测试重定向规则
若要测试使用“StaticRedirects”映射的重写规则,请打开 Web 浏览器并请求以下任意 URL:
http://localhost/old-article
http://localhost/posts/default.aspx?id=1
http://localhost/old-title.html
上述任何一个 URL 都会导致浏览器重定向到 http://localhost/article.aspx?id=1
。
对查询字符串参数使用重写映射
重写映射的使用不局限于上述示例。 重写映射是键值对的泛型集合,可以在重写规则中的任何位置使用。 为了说明这一点,让我们创建一个可用于操作查询字符串参数的重写映射。
按照创建重写映射部分中所述的相同步骤创建第三个重写映射。 将重写映射命名为“IDtoTitleMap”并使用以下映射条目值:
原始值: | 新值: |
---|---|
1 | some-title-1 |
2 | some-title-2 |
3 | some-title-3 |
网站的 web.config 文件现在应包含以下两个重写映射:
<rewriteMaps>
<rewriteMap name="StaticRewrites">
<add key="/article1" value="/article.aspx?id=1&title=some-title" />
<add key="/some-title" value="/article.aspx?id=1&title=some-title" />
<add key="/post/some-title.html" value="/article.aspx?id=1&title=some-title" />
</rewriteMap>
<rewriteMap name="StaticRedirects">
<add key="/old-article.aspx?id=1" value="/article.aspx?id=1" />
<add key="/posts/default.aspx?id=1" value="/article.aspx?id=1" />
<add key="/old-title.html" value="/article.aspx?id=1" />
</rewriteMap>
<rewriteMap name="IDtoTitleMap">
<add key="1" value="some-title-1" />
<add key="2" value="some-title-2" />
<add key="3" value="some-title-3" />
</rewriteMap>
</rewriteMaps>
若要创建使用 IDtoTitleMap 重写映射的规则,请将以下规则定义复制并粘贴到网站的 web.config 文件中:
<rules>
<rule name="Query String Rule" stopProcessing="true">
<match url="^article\.aspx$" />
<conditions>
<add input="{QUERY_STRING}" pattern="(?:^|&)id=([0-9]+)(?:&|$)" />
<add input="{IDtoTitleMap:{C:1}}" pattern="(.+)" />
</conditions>
<action type="Redirect" url="article.aspx?title={C:1}" appendQueryString="False"
redirectType="Permanent" />
</rule>
</rules>
让我们仔细查看每个规则元素以了解其作用:
<match url="^article\.aspx$" />
- 此元素告知 URL 重写模块在请求 article.aspx 文件时执行该规则。
<add input="{QUERY\_STRING}" pattern="(?:^|&)id=([0-9]+)(?:&|$)" />
- 此条件检查查询字符串是否包含采用数值的参数 id。 实际值在条件反向引用中捕获。 请注意,即使查询字符串包含其他参数,此模式也将起作用。
<add input="{IDtoTitleMap:{C:1}}" pattern="(.+)" />
- 此条件检查从重写映射 IDtoTitleMap 返回的值是否不是空字符串。 该条件使用前一个条件模式的反向引用作为重写映射的输入。
<action type="Redirect" url="article.aspx?title={C:1}" appendQueryString="False" redirectType="Permanent" />
- 此元素指定 URL 重写模块需要将 Web 客户端重定向回 Article.aspx 文件,但使用不同的查询字符串参数 title,该参数采用在重写映射中查找的值。
测试针对查询字符串的规则
若要测试使用“IDtoTitleMap”映射的重写规则,请打开 Web 浏览器并请求以下任意 URL:
http://localhost/article.aspx?id=1
。 将重定向到 http://localhost/article.aspx?title=some-title-1. http://localhost/article.aspx?someparam=somevalue&id=2
。 将重定向到 http://localhost/article.aspx?title=some-title-2
总结
在本演练中,你已了解如何使用重写映射来定义重写和重定向规则的 URL 映射。 此外,你还了解了如何使用重写映射来操作查询字符串参数。
当重写和重定向 URL 是静态的并且无法使用任何模式匹配技术来表达重写逻辑时,使用重写映射可以减少重写规则的数量。