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如何來處理響應)