URL 重写模块将请求 URL 重写为向用户或 Web 应用程序中显示的简单、用户友好和搜索引擎友好地址。 URL 重写使用定义的规则进行评估,然后将请求 URL 映射到规则中定义的地址,然后再由 IIS Web 服务器处理。 可以定义包含正则表达式和通配符的 URL 重写逻辑,并且可以基于请求 URL、HTTP 标头和服务器变量应用规则。 虽然模块的主要用途是将请求 URL 重写为更友好的 URL,但也可以使用该模块来定义执行重定向、发送自定义响应或中止请求的规则。
重写规则概述
重写规则定义要比较或匹配请求 URL 的逻辑,以及如果比较成功,该怎么办。
重写规则包含以下部分:
模式
– 规则模式用于指定正则表达式或用于匹配 URL 字符串的通配符模式。
条件
– 可选条件集合用于指定在 URL 字符串与规则模式匹配时要执行的附加逻辑作。 在条件中,可以检查 HTTP 标头或服务器变量的某些值,或者验证请求的 URL 是否对应于物理文件系统上的文件或目录。
动作
– 动作用于指定当 URL 字符串与规则模式匹配并满足所有规则条件时应执行的操作。
重写规则的适用范围
可以在两个不同的集合中定义重写规则:
<globalRules>
– 此集合中的规则只能在服务器级别定义。 全局规则用于定义服务器范围的 URL 重写逻辑。 这些规则在 ApplicationHost.config 文件中定义,无法在任何较低的配置级别上重写或禁用这些规则。 全局规则始终在绝对 URL 的路径上运行(即请求的 URI,没有服务器名称)。 这些规则是在 IIS 请求处理管道(
PreBeginRequest
事件)的早期评估的。
<rules>
– 此集合中的规则称为分布式规则,可以在配置层次结构中的任何级别上定义它们。 分布式规则用于定义特定于特定配置范围的 URL 重写逻辑。 可以使用 Web.config 文件或使用
<location>
ApplicationHost.config 或 Web.config 文件中的标记在任何配置级别添加这种类型的规则。 分布式规则在 URL 路径上运行,参考它们定义所在的 Web.config 文件的位置。 如果分布式规则在
<location>
标记内部定义,则它们对 URL 路径进行操作,相对于为该
<location>
标记指定的路径。 这些规则在 IIS 管道中的 BeginRequest 事件上进行评估。
IIS 中的每个配置级别都可以定义零个或多个重写规则。 规则的评估顺序与指定规则的顺序相同。 URL 重写模块使用以下算法处理规则集:
首先,URL 与规则模式匹配。 如果不匹配,URL 重写模块会立即停止处理该规则,然后转到下一个规则。
如果模式匹配且规则没有条件,URL 重写模块将执行为此规则指定的作,然后转到下一个规则,在该规则中,它将替换的 URL 用作该规则的输入。
如果模式匹配并且规则有条件,URL 重写模块将评估条件。 如果评估成功,则执行指定的规则操作,然后将重写后的 URL 作为后续规则的输入。
规则可能已启用
StopProcessing
标志。 规则执行(即规则匹配)并打开此标记时,这意味着将不会处理任何后续规则,请求会直接传递到IIS请求管道。 默认情况下,此标志处于关闭状态。
如果规则在多个配置级别上定义,则 URL 重写模块按以下顺序评估规则:
评估所有全局规则。
评估包含父配置级别的分布式规则以及当前配置级别的规则集。 评估按父到子规则顺序进行,这意味着先评估父规则,最后在最后一个子级别上定义的规则被评估。
保留原始 URL
URL 重写模块在以下服务器变量中保留原始请求的 URL 路径:
HTTP_X_ORIGINAL_URL
– 此服务器变量包含解码格式的原始 URL;
UNENCODED_URL
– 此服务器变量包含与 Web 客户端请求的原始 URL 完全一样,保留所有原始编码。
通过重写规则访问 URL 组成部分
请务必了解如何从重写规则访问 URL 字符串的某些部分。
对于以下形式的 HTTP URL:http(s)://<host>:<port>/<path>?<querystring>
<路径>被与规则的模式匹配。
查询 <字符串> 在名为QUERY_STRING的服务器变量中可用,并且可以使用规则中的条件进行访问。
主机<>在服务器变量HTTP_HOST中可用,可以使用规则中的条件进行访问。
该 <端口> 在服务器变量SERVER_PORT中可用,可以使用规则中的条件进行访问。
服务器变量SERVER_PORT_SECURE和 HTTPS 可用于确定是否使用了安全连接。 可以使用规则中的条件来访问这些服务器变量。
服务器变量REQUEST_URI可用于访问整个请求的 URL 路径,包括查询字符串。
例如,如果对这个 URL 发出了请求:
http://www.mysite.com/content/default.aspx?tabid=2&subtabid=3
并在网站级别定义了重写规则,那么:
规则模式接收 URL 字符串
content/default.aspx
作为输入。
QUERY_STRING服务器变量包含
tabid=2&subtabid=3
。
HTTP_HOST服务器变量包含
www.mysite.com
。
SERVER_PORT服务器变量包含
80
。
SERVER_PORT_SECURE服务器变量包含
0
和 HTTPS 包含
OFF
。
REQUEST_URI服务器变量包含
/content/default.aspx?tabid=2&subtabid=3
。
PATH_INFO服务器变量包含
/content/default.aspx
。
请注意,传递给分布式规则的输入 URL 字符串始终相对于定义规则 Web.config 文件的位置。 例如,如果发出
http://www.mysite.com/content/default.aspx?tabid=2&subtabid=3
请求并在
/content
目录中定义重写规则,则该规则将获取此 URL 字符串
default.aspx
作为输入。
重写规则配置
重写规则模式用于指定与当前 URL 路径进行比较的模式。 在此上下文中,当前表示应用规则时 URL 路径的值。 如果存在当前规则之前的任何规则,则它们可能已匹配原始请求的 URL 并对其进行修改。 根据模式计算的 URL 字符串不包括查询字符串。 若要在规则计算中包含查询字符串,可以在规则的条件中使用QUERY_STRING服务器变量。 有关详细信息,请参阅
“在重写规则中使用服务器变量”。
在重写规则的<匹配>元素中指定模式。
规则模式语法
可以使用规则的
patternSyntax
属性来指定规则模式语法。 此属性可设置为以下选项之一:
ECMAScript
– Perl 兼容(ECMAScript 标准兼容)正则表达式语法。 这是任何规则的默认选项。 这是模式格式的示例:“^([_0-9a-zA-Z-]+/)?(wp-.*)”
通配符
– IIS HTTP 重定向模块中使用的
通配符
语法。 下面是采用以下格式的模式示例:“/Scripts/*_in.???”,其中星号(“*”)表示“匹配任意数量的任意字符并在后引用中捕获它们”和“?” 表示完全匹配一个字符(未创建反向引用)。
patternSyntax
属性的范围是每个规则,这意味着它适用于当前规则的模式以及在该规则的条件中使用的所有模式。
规则模式属性
可以使用匹配>元素的<
否定
属性来否定模式。 使用此属性时,仅当当前 URL 与指定的模式
不匹配
时,才会执行规则作。
默认情况下,使用不区分大小写的模式匹配。 若要启用区分大小写,可以使用规则的
ignoreCase
属性在 <match> 元素中。
规则条件允许定义规则评估的其他逻辑,该逻辑可以基于除当前 URL 字符串以外的输入。 任何规则都可以有零个或多个条件。 规则条件在规则模式匹配成功后进行评估。
条件是在<条件>集合中的重写规则中定义的。 此集合具有一个名为
logicalGrouping
的属性,用于控制条件的计算方式。 如果规则有条件,则仅当规则模式匹配并且:
所有条件都计算为 true,前提是使用了
logicalGrouping=“MatchAll”。
如果使用了
logicalGrouping=“MatchAny”
,则至少有一个条件被计算为 true。
通过指定以下属性来定义条件:
输入字符串
条件输入指定要用作条件评估输入的项。 条件输入是一个任意字符串,可以包括服务器变量和对以前的条件模式和/或规则模式的回引用。
匹配类型可以是以下三个选项之一:
IsFile
– 此匹配类型用于确定输入字符串是否包含文件系统上文件的物理路径。 如果未指定条件输入字符串,URL 重写模块将使用请求的文件的物理路径作为条件输入的默认值。 此匹配类型只能用于分布式规则。
IsDirectory
– 此匹配类型用于确定输入字符串是否包含文件系统上目录的物理路径。 如果未指定条件输入字符串,URL 重写模块将使用请求的文件的物理路径作为条件输入的默认值。 此匹配类型只能用于分布式规则。
模式
– 此匹配类型用于表示任意输入字符串与正则表达式模式匹配的条件。 可以使用正则表达式语法或使用通配符语法来指定条件模式。 要在条件中使用的模式类型取决于为此条件所属的规则定义的
patternSyntax
标志的值。 此条件类型具有两个控制模式匹配的相关属性:
pattern
– 使用此属性指定实际模式。
ignoreCase
– 使用此属性控制条件的模式匹配是否应区分大小写或不区分大小写。
此外,可以使用
求反
特性来否定条件评估的结果。 这可用于指定一个条件,用于检查请求的 URL 是否不是文件,如以下示例所示:
<add input="{REQUEST_FILENAME}" matchType="isFile" negate="true">
当当前 URL 与规则模式匹配且条件评估成功(具体取决于规则配置、匹配的所有条件或匹配的任何一个或多个条件)时,将执行重写规则作。 有几种操作类型可用,操作配置元素的类型属性可用于指定规则执行的操作。 以下部分介绍与特定作类型相关的不同作类型和配置选项。
重写作将当前 URL 字符串替换为替换字符串。 替换字符串必须始终指定 URL 路径(例如 contoso/test/default.aspx)。 请注意,IIS 不支持在文件系统(例如, C:\inetpub\wwwroot)上包含物理路径的替换。
重写操作具有以下配置选项:
url – 这是重写当前 URL 时要使用的替换字符串。 替换 URL 是一个字符串值,可以包括以下内容:
对条件和规则模式的反向引用。 (有关详细信息,请参阅有关如何使用后引用的部分。
服务器变量。 (有关详细信息,请参阅有关如何使用服务器变量的部分。
appendQueryString – 指定替换期间是否保留来自当前 URL 的查询字符串。 默认情况下,如果未指定 appendQueryString 标志的值,则假定为 TRUE。 这意味着原始 URL 中的查询字符串将追加到替换的 URL。
重定向操作
重定向动作指示 URL 重写模块将重定向响应发送回客户端。 可以将重定向状态代码 (3xx) 指定为此作的参数。 响应的 “位置” 字段包含规则中指定的替换字符串。
可以在以下格式之一中指定重定向规则的替换 URL:
相对 URL 路径 - contoso/test/default.aspx
绝对 URI - https://example.com/contoso/test/default.aspx
重定向作的使用意味着在执行 重定向 后,不会评估当前 URL 的后续规则。
重定向作具有以下配置选项:
url - 使用替换字符串作为重定向 URL。 替换 URL 是可以包含以下内容的字符串:
对条件和规则模式的反向引用。 (有关详细信息,请参阅有关如何使用后引用的部分。
服务器变量。 (有关详细信息,请参阅有关如何使用服务器变量的部分。
appendQueryString – 指定替换期间是否应保留当前 URL 中的查询字符串。 默认情况下,如果未指定 AppendQueryString 标志,则假定其为 TRUE。 这意味着原始 URL 中的查询字符串将追加到替换的 URL。
redirectType – 指定要在重定向期间使用的状态代码:
301 – 永久
302 – 已找到
303 - 请参阅其他
307 – 临时
URL 重写模块不支持 HTTP 状态代码 308(永久重定向)。
CustomResponse操作
CustomResponse作会导致 URL 重写模块通过用户指定的状态代码、子代码和原因来响应 HTTP 客户端。 使用 CustomResponse 操作意味着在执行此操作后不会对当前 URL 的后续规则进行评估。
CustomResponse动作具有以下配置选项:
statusCode – 指定要用于响应客户端的状态代码。
subStatusCode – 指定要用于响应客户端的子状态代码。
statusReason – 指定用于状态代码的原因短语。
statusDescription – 指定要放入响应正文中的一行说明。
AbortRequest动作
AbortRequest作会导致 URL 重写模块删除当前请求的 HTTP 连接。 该操作没有任何参数。 使用此操作意味着在执行此操作后,不会评估当前 URL 的后续规则。
None用于指定不执行任何动作。
在重写规则中使用服务器变量
服务器变量提供有关当前 HTTP 请求的其他信息。 可以使用此信息来做出重写决策或构建新的 URL。 可以在重写规则中的以下位置引用服务器变量:
在条件输入字符串中
在规则替换字符串中,具体而言:
重写和重定向操作的 url 属性
CustomResponse action的statusLine和responseLine
可以使用 {VARIABLE_NAME} 语法引用服务器变量。 例如,以下条件使用QUERY_STRING服务器变量:
<add input="{QUERY_STRING}" pattern="id=([0-9]+)" />
服务器变量还可用于从当前请求访问 HTTP 标头。 由当前请求提供的任何 HTTP 标头都表示为服务器变量,该变量具有根据此命名约定生成的名称:
HTTP 标头名称中的所有短划线(“-”)符号都转换为下划线符号(“_”)。
HTTP 标头名称中的所有字母都转换为大写。
“HTTP_”前缀将添加到标头名称中。
例如,若要从重写规则访问 HTTP 标头“user-agent”,可以使用 {HTTP_USER_AGENT} 服务器变量。
在重写规则中使用后退引用
可以在反向引用中捕获规则或条件输入的一部分。 然后,这些 URL 可用于在规则作中构造替换 URL,或为规则条件构造输入字符串。
返回引用以不同的方式生成,具体取决于规则使用哪种类型的模式语法。 使用 ECMAScript 模式语法时,可以通过将括号放在必须捕获后引用的模式部分周围来创建反向引用。 例如,模式 ([0-9]+)/([a-z]+).html 将从此请求的 URL 中捕获 07 和 文章 : 07/article.html。 使用“通配符”模式语法时,只要在模式中使用星号符号(*),就始终会创建后引用。 在模式中使用“?” 时,不会创建任何后退引用。 例如,模式 */*.html 将在这个请求的 URL 中捕获 contoso 和 test 的回引用:contoso/test.html。
无论使用哪种模式语法来捕获它们,反向引用的用法都是相同的。 可以在重写规则中的以下位置使用反向引用:
条件输入字符串
在规则动作中,具体而言:
重写和重定向动作的 url 属性
statusLine 和 responseLine 属于 CustomResponse 操作
在重写映射中作为一个关键参数
条件模式的反向引用由 {C:N} 标识,其中 N 从 0 到 9。 对规则模式的后退引用由 {R:N} 标识,其中 N 从 0 到 9。 请注意,对于这两种类型的背引用,{R:0} 和 {C:0} 都将包含匹配的字符串。
例如,在此模式中:
^(www\.)(.*)$
对于字符串:www.foo.com,反向引用将按如下索引:
{C:0} - www.foo.com
{C:1} - www.
{C:2} - foo.com
在规则操作中,可以使用对规则模式的后向引用以及该规则中的最后匹配条件。 在条件输入字符串中,可以使用对规则模式和以前匹配的条件的后退引用。
以下规则示例演示如何创建和引用反向引用:
<rule name="Rewrite subdomain">
<match url="^(.+)" /> <!-- rule back-reference is captured here -->
<conditions>
<add input="{HTTP_HOST}" type="Pattern" pattern="^([^.]+)\.mysite\.com$" /> <!-- condition back-reference is captured here -->
</conditions>
<action type="Rewrite" url="{C:1}/{R:1}" /> <!-- rewrite action uses back-references to condition and to rule when rewriting the url -->
</rule>
与 IIS 输出缓存交互
URL 重写模块控制 IIS 输出缓存行为,以便:
以最佳方式利用内核模式和用户模式输出响应的重写 URL 缓存,从而提高使用 URL 重写模块的 Web 应用程序的性能。
防止缓存响应,因为 URL 重写可能会违反缓存逻辑。
模块通过更改某些缓存属性或完全禁用缓存来控制输出缓存。 如果 IIS 配置或 IIS 管道中的任何其他模块禁用了输出缓存,则模块无法启用输出缓存。 输出缓存按如下所示进行控制:
该模块始终设置用户模式缓存设置 varyByHeader=“HTTP_X_ORIGINAL_URL”。 这可确保启用用户模式缓存时,模块会考虑原始 URL 来构造缓存条目的密钥。
如果重写规则集使用服务器变量,其值要么是进程整个生命周期中的常量,要么派生自请求的 URL,则规则集被视为安全用于输出缓存。 这意味着 URL 重写模块不会以除设置 varyByHeader 以外的任何方式更改现有缓存策略,如步骤 1 中所述。
在重写规则中使用时,以下服务器变量不会对输出缓存策略产生任何影响:
“CACHE_URL”
“DOCUMENT_ROOT”
“HTTP_URL”
“HTTP_HOST”
“PATH_INFO”
“PATH_TRANSLATED”
“QUERY_STRING”
“REQUEST_FILENAME”
“REQUEST_URI”
“SCRIPT_FILENAME”
“SCRIPT_NAME”
“SCRIPT_TRANSLATED”
“UNENCODED_URL”
“URL”
“URL_PATH_INFO”
“”APP_POOL_ID”
“APPL_MD_PATH”
“APPL_PHYSICAL_PATH”
“GATEWAY_INTERFACE”
服务器_软件
“SSI_EXEC_DISABLED”
如果重写规则集使用上述列表中未提及的任何服务器变量,则规则集被视为不安全的输出缓存。 这意味着,无论是否重写请求 URL,URL 重写模块都会为所有请求禁用内核模式缓存。 此外,该模块将通过设置缓存属性 varyByValue 来更改用户模式缓存的缓存策略,以包含规则集中使用的所有服务器变量值的串联字符串。
字符串函数
有三个字符串函数可用于更改重写规则作中的值,以及任何条件:
ToLower - 返回转换为小写的输入字符串。
UrlEncode - 返回转换为 URL 编码格式的输入字符串。 如果重写规则中的替换 URL 包含特殊字符(例如非 ASCII 或 URI 不安全字符),则可以使用此函数。
UrlDecode - 解码 URL 编码的输入字符串。 此函数可用于解码条件输入,然后再将其与模式匹配。
可以使用以下语法调用这些函数:
{function_name:any_string}
其中,“function_name”可能位于以下位置:“ToLower”、“UrlEncode”、“UrlDecode”。 “Any_string”可以是文本字符串,也可以是使用服务器变量或反向引用生成的字符串。 例如,下面是字符串函数的有效调用:
{ToLower:DEFAULT.HTM}
{UrlDecode:{REQUEST_URI}}
{UrlEncode:{R:1}.aspx?p=[résumé]}
字符串函数可用于重写规则中的以下位置:
条件输入字符串
在规则替换字符串中,具体而言:
重写和重定向动作的url属性
CustomResponse 操作的 statusLine 和 responseLine 属性
使用 ToLower 函数的规则示例:
<rule name="Redirect to canonical url">
<match url="^(.+)" /> <!-- rule back-reference is captured here -->
<conditions>
<!-- Check whether the requested domain is in canonical form -->
<add input="{HTTP_HOST}" type="Pattern" pattern="^www\.mysite\.com$" negate="true" />
</conditions>
<!-- Redirect to canonical url and convert URL path to lowercase -->
<action type="Redirect" url="http://www.mysite.com/{ToLower:{R:1}}" redirectType="Found" />
</rule>
使用 UrlEncode 函数的规则示例:
<rules>
<rule name="UrlEncode example" stopProcessing="true">
<match url="resume" />
<action type="Rewrite" url="default.aspx?name={UrlEncode:résumé}"/>
</rule>
使用 UrlDecode 函数的规则示例:
<rules>
<rule name="UrlDecode example">
<match url="default.aspx" />
<conditions>
<add input="{UrlDecode:{QUERY_STRING}}" pattern="résumé" />
</conditions>
<action type="Rewrite" url="default.aspx?type=resume" />
</rule>
</rules>
重写映射是名称值对的任意集合,可在重写规则中使用,在重写过程中生成替换 URL。 重写映射在处理大量重写规则且这些规则都使用静态字符串(即,没有使用模式匹配)时特别有用。 在这些情况下,可以将所有映射作为输入 URL 和替换 URL 之间的键和值放入重写映射中,而不是定义一组大型简单重写规则。 然后,若要根据输入 URL 查找替换 URL,你将有一个引用重写映射的重写规则。
重写映射定义一个命名的键值对字符串集合,如以下示例所示:
<rewriteMap name="MyRewriteMap" defaultValue="">
<add key="a.html" value="b.html" />
<add key="c.aspx" value="d.aspx" />
<add key="e.php" value="f.php" />
</rewriteMap>
重写映射由其名称唯一标识,可以包含零个或多个键值条目。 此外,重写映射还可以指定在找不到键时要使用的默认值。 这是通过使用 defaultValue 属性控制的。 默认情况下,空字符串用作默认值。
除文件级别外,任何配置级别上可以有任意数量的重写映射。 重写映射位于<rewriteMaps> 集合元素中。
在重写规则中引用重写映射时,需使用以下语法:
{RewriteMapName:Key}
其中 Key 参数可以是任意字符串,并且可以包含对规则或条件模式的后退引用。 例如,下面是重写映射的几种可能用法:
{MyRewriteMap:contoso/{R:1}/test/{C:1}}
{MyRewriteMap:a.html}
{MyRewriteMap:{R:1}?{C:1}&contoso=test}
重写映射的引用将替换为使用重写映射引用中作为参数传递的键查找的值。 如果未找到密钥,将使用该重写映射的默认值。
可以在重写规则中的以下位置引用重写映射:
条件输入字符串
在规则替换字符串中,具体而言:
重写和重定向动作的url属性
CustomResponse 操作的 statusLine 和 responseLine
<rewriteMaps>
<rewriteMap name="StaticRewrites" defaultValue="">
<add key="/diagnostics" value="/default.aspx?tabid=2&subtabid=29" />
<add key="/webcasts" value="/default.aspx?tabid=2&subtabid=24" />
<add key="/php" value="/default.aspx?tabid=7116" />
</rewriteMap>
</rewriteMaps>
</rewrite>
重写规则的定义如下:
<rewrite>
<rule name="Rewrite Rule">
<match url=".*" />
<conditions>
<add input="{StaticRewrites:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Rewrite" url="{C:1}"/>
</rule>
</rewrite>
请求的 URL /diagnostic 将重写为 /default.aspx?tabid=2&subtabid=29。
请求的 URL /webcasts 将重写为 /default.aspx?tabid=2&subtabid=24。
请求的 URL /php 将重写为 /default.aspx?tabid=7116。
不会重写请求的 URL /default.aspx ,因为重写映射不包含 key=“/default.aspx”的元素;因此,重写映射将返回一个与条件模式不匹配的空字符串,因此不会执行规则作。
示例 2:重写映射的定义如下:
<rewrite>
<rewriteMaps>
<rewriteMap name="StaticRedirects" defaultValue="">
<add key="/default.aspx?tabid=2&subtabid=29" value="/diagnostics" />
<add key="/default.aspx?tabid=2&subtabid=24" value="/webcasts" />
<add key="/default.aspx?tabid=7116" value="/php" />
</rewriteMap>
</rewriteMaps>
</rewrite>
重写规则的定义如下:
<rewrite>
<rule name="Redirect rule">
<match url=".*" />
<conditions>
<add input="{StaticRedirects:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Redirect" url="http://www.contoso.com{C:1}" redirectType="Found" />
</rule>
</rewrite>
请求的 URL /default.aspx?tabid=2&subtabid=29 将重定向到 http://www.contoso.com/diagnostics。
请求的 URL /default.aspx?tabid=2&subtabid=24 将重定向到 http://www.contoso.com/webcasts。
请求的 URL /default.aspx?tabid=7116 将重定向到 http://www.contoso.com/php。
不会重定向请求的 URL /default.aspx ,因为重写映射不包含 key=“/default.aspx”的元素;因此,重写映射将返回一个与条件模式不匹配的空字符串,因此不会执行规则作。