Url Rewrite是IIS的一个扩展。我们可以利用它来为网站创造出强大重定向与重写请求与响应的功能。甚至可以结合Application Request Routing(ARR)提供反向代理的功能。
请求重定向
请求重定向主要通过定义Inbound Rule来定义请求的匹配规则以及重定向规则。其主要有一下元素组成:
元素 | 说明 | |
名字 | 请求的名称 | |
Match URL |
这个主要是用来定义Rule需要匹配的请求Url(Url Path中/后面的字符串)。 |
支持正则匹配,通配符匹配,精确匹配(支持正向或反向匹配) |
Condition |
在Match URL匹配通过的前提下,我们还可以通过添加Condition的方式对请求其他部分(例如:Header)进行匹配。 |
我们可以定义一个或多个Condition。 支持Server Variable(通过Server Variable获取Request Header)做为Condition的匹配input,支持正则匹配 |
Action |
通过Match Url和Condition,我们可以定义要匹配的请求。Action用来定义对匹配到的请求的操作。 |
支持Rewrite和Redirect等操作。 Redirect则是向浏览器发送重定向响应。 (支持正则反向引用来定义Rewrite/Redirect的Url) |
Rule的定义可以通过IIS Manager以可视化方式定义,也可以通过在web.config中以配置的形式定义。(可视化方式会自动生成web.config中的配置)
举例:(将http://localhost:8080/rewrite/index.html?time=now重定向为http://localhost:8080/rewrite/index.html?time=now)
<rewrite> <rules> <rule name="FolderRewrite" stopProcessing="true"> <match url="([a-zA-Z0-9]+)/([a-zA-z0-9]+).html" /> <conditions> <add input="{QUERY_STRING}" pattern=".*" /> </conditions> <action type="Redirect" url="/{R:2}.html?{C:0}" appendQueryString="false" />
<!--反向引用{R:2}引用的是match中的第二个匹配项,{R:0}为pattern匹配到字符串,{C:0}引用的是condition中pattern匹配到的字符串--> </rule> </rules> </rewrite>
结果:
修改响应信息
响应信息的修改是通过定义Outbound Rule来定义匹配规则以及修改规则。可以通过Outbound Rule来修改,添加Response Header/Body.Outbound Rule的主要组成元素如下:
元素 | 说明 | |
名字 | 请求的名称 | |
Match |
这个主要是用来定义Rule需要匹配的响应的条件以及要匹配和操作的目标。 |
支持匹配Response和Server Variable. 如果是匹配Response的话可以定义匹配部分html标签的特定attribute. 如果是匹配Server Variable的话,Response header对应的Server Variable Name是在Server Variable基础上用RESPONSE 代替HTTP前缀。 |
Condition |
在Match匹配通过的前提下,我们还可以通过添加Condition的方式对请求其他部分(例如:Header)进行匹配。 |
我们可以定义一个或多个Condition。 支持Server Variable(通过Server Variable获取Request Header)做为Condition的匹配input,支持正则匹配 |
Action |
定义对匹配到的目标的操作(Rewrite) |
跟Inbound Rule一样,支持正则反向引用。对于Server Variable,如果Web服务器的响应头未包含某个Header,通过Server Variable的反向匹配 也能匹配到,然后修改其值。相当于为响应添加了Header。 |
举例:
1. 为Cookie添加Lax SameSite attribute
由于在某些场景下,我们无法通过代码来为Cookie添加SameSite attribute(e.g ASP.NET 4.5)。这样的话我们便可以通过UrlRewrite来修改响应信息为Cookie添加上SameSite attribute.只需要创建如下一个Outbound Rule.
<rule name="LoginLaxCookie" enabled="true"> <match serverVariable="RESPONSE_Set-Cookie" pattern="^(.*)(LoginCookie.localhost)(=.*)$" /> <!--匹配Response中的Set-Cookie头,配置条件为值包含LoginCookie.localhost=字符串--> <action type="Rewrite" value="{R:0};SameSite=Lax;" /> <!--对匹配到目标的操作为在源字符串后面加上;SameSite=Lax;--> </rule>
2. 为Response添加Header
<rule name="PortalCORS"> <match serverVariable="RESPONSE_Access-Control-Allow-Origin" pattern=".+" negate="true" /> <!--反向匹配,未匹配到满足条件的值算匹配成功--> <action type="Rewrite" value="*" /><!--替换Header的值为*,因为Header Access-Control-Allow-Origin原本不存在,所以相当于添加了Header--> </rule>
总结:UrlRewrite类似于IIS的一个中间件,
1. IIS接收到的请求会先流过UrlRewrite组件(在这个环节中,我们可以通过定义InBound Rule来控制UrlRewrite如何来处理请求),
2. 在Web App生成Response后也会流过Url Rewrite组件(在这个环节中,我们可以通过定义Outbound Rule来控制UrlRewrite如何来处理响应)