Share via


URL 重寫模組 2.0 組態參考

Ruslan Yakushev

本檔的這一節適用於 IIS 7 的 URL Rewrite Module 2.0 版

本文提供 URL Rewrite Module 2.0 功能的概觀,並說明此版本中使用的新組態概念。 如需 URL 重寫模組 1.1 組態的詳細資訊,請參閱 URL 重寫模組組態參考

目錄

功能概觀

適用於 IIS 的 Microsoft URL Rewrite Module 2.0 是累加版本,其中包含 1.1 版的所有功能,並新增響應標頭和內容重寫的支援。 模組會將正則表示式或通配符模式套用至 HTTP 回應,以根據輸出重寫規則所表示的重寫邏輯來尋找和取代內容元件。 更具體來說,模組可以用來:

  • 將回應 HTML 中 Web 應用程式所產生的 URL 取代為更方便使用且搜尋引擎易記的對等專案。
  • 修改 Web 應用程式在反向 Proxy 後方產生的 HTML 標記中的連結。
  • 修改現有的 並設定新的回應 HTTP 標頭。
  • 修正任何 HTTP 回應的內容,包括 JavaScript、CSS、RSS 等。

警告

當響應標頭或響應內容由輸出重寫規則修改時,應特別小心,以確保插入回應中的文字不包含任何用戶端可執行程序代碼,這可能會導致跨網站腳本弱點。 當重寫規則使用不受信任的數據,例如 HTTP 標頭或查詢字串,來建置要插入 HTTP 回應的字串時,這特別重要。 在這種情況下,取代字串應該使用 HtmlEncode 函式進行 HTML 編碼,例如:

<action type="Rewrite" value="{HtmlEncode:{HTTP_REFERER}}" />

輸出規則概觀

用於回應重寫的主要組態概念是輸出規則的概念。 輸出規則可用來表達要比較或比對回應內容的邏輯,以及在比較成功時該怎麼辦。

從概念上講,輸出規則包含下列部分:

  • Pre-condition - 選擇性的預先條件是用來檢查要求元數據,然後才開始評估任何規則。 預先條件可能包含對要求元數據的數個條件式檢查,而且可用來篩選出不應該重寫的回應,例如影像或視訊檔案。
  • 標籤篩選 - 標籤篩選 可用來縮小回應中對一組已知或自定義定義標籤的搜尋範圍。 使用標籤篩選時,只會比對指定標籤的內容與規則模式,而不是比對整個響應內容與模式。
  • Pattern – 規則模式可用來指定正則表示式或通配符模式,以用於在響應內容內搜尋。
  • 條件 – 選擇性條件 集合可用來指定在響應內容中找到模式相符項目時執行的其他邏輯作業。 在條件中,您可以檢查 HTTP 標頭或伺服器變數的特定值。
  • 動作 – 此動作可用來指定找到模式比對,且所有規則條件都已成功評估時要執行的動作。

規則執行

執行輸出規則的程式與用於輸入規則的程式不同。 輸入規則集只會針對每個要求評估一次,因為其輸入只是單一要求URL字串。 每個回應可能會評估輸出規則集多次,因為其套用在 HTTP 回應內容內的多個位置。 例如,如果有規則集,如下所示:

規則 1:適用於<>標記和 <img> 標籤

規則 2:適用於<>標記

與 HTML 回應包含此標記:

<a href="/default.aspx"><img src="/logo.jpg" />Home Page</a>

然後 URL 重寫模組 2.0 會針對 “/default.aspx” 字串評估規則 1。 如果已成功執行規則,則會將規則 1 的輸出提供給 Rule2。 如果成功執行規則 2,則規則 2 的輸出將用來取代回應中標記中 <> href 屬性的內容。

在該 URL 重寫模組 2.0 之後,會根據 “/logo.jpg” 字串評估 Rule1。 如果成功執行規則,則會使用其輸出來取代回應中 img> 標籤中 <src 屬性的內容。

規則繼承

如果規則是在多個組態層級上定義,則URL重寫模組會評估規則集,其中包含父組態層級的分散式規則,以及來自目前組態層級的規則。 評估是以父對子順序執行,這表示先評估父規則,最後一次評估最後一個子層級上定義的規則。

輸出規則組態

Pre-conditions 集合

預先條件可用來檢查是否應針對回應內容評估規則。 預先條件集合定義為 preConditions> 區段中的具名集合<,而且可能包含一或多個預先條件檢查。 輸出規則會依名稱參考條件前集合。

條件前集合具有稱為 logicalGrouping 的屬性,可控制條件的評估方式。 如果:

  • 內的所有預先條件都評估為 true,前提是已使用 logicalGrouping=“MatchAll”。
  • 如果 已使用logicalGrouping=“MatchAny” ,則至少有一個預先條件評估為 true。

預先條件是藉由指定下列屬性來定義:

  • 輸入字串 - 條件前輸入會指定要作為條件評估輸入的專案。 前置條件輸入是任意字串,可包含伺服器變數和先前條件前模式的反向參考。
  • 模式 - 預先條件模式可以使用正規表示式語法或使用通配符語法來指定。 在預先條件中使用的模式類型取決於針對預先條件集合定義的 patternSyntax 旗標值

此外,您可以使用否定屬性來否定預先條件評估的結果。

預先條件的範例,會檢查回應內容類型是否為 text/html:

<preConditions>
    <preCondition name="IsHTML">
        <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
    </preCondition>
</preConditions>

標籤篩選

標籤可用來將回應內容內的搜尋縮小到一組已知或自定義定義的 HTML 標記。 當重寫規則接著使用標籤篩選時,URL Rewrite Module 2.0 會尋找規則標籤篩選中所列的 HTML 標籤,然後取得該標籤的 URL 屬性內容,並根據規則的模式進行評估。 標記篩選是在輸出規則之 match> 元素的 <filterByTags 屬性內指定。 例如:

<match filterByTags="A" pattern="^/(article\.aspx.*)" />

如果 HTTP 回應包含錨點標記,例如:

<a href="/article.aspx?id=1">link</a>

然後會根據字串評估重寫規則模式:「article.aspx?id=1」。

預先定義的標記

URL Rewrite Module 2.0 包含一組預先定義的標記,可搭配輸出規則使用。 下表列出所有預先定義的標記和屬性,其值將作為輸出規則模式的輸入:

標籤 屬性
A href
區域 href
Base href
表單​​ action
Frame src,longdesc
前端 profile
IFrame src,longdesc
影像 src, longdesc, usemap
輸入 src, usemap
連結 href
指令碼 src

自訂標籤

如果需要在未包含在預先定義標籤集合的標籤屬性內執行重寫,則可以使用自定義標籤集合來指定標籤名稱和需要重寫的對應屬性。 自定義標記集合會定義為 customTags> 區段中的<具名集合。 輸出規則會依名稱參考自定義標籤集合。

下列範例顯示自訂標籤集合的定義:

<customTags>
    <tags name="My Tags">
        <tag name="item" attribute="src" />
        <tag name="element" attribute="src" />
    </tags>
</customTags>

您可以從輸出規則參考此自訂標籤集合,如下列範例所示:

<match filterByTags="A, CustomTags" customTags="My Tags" pattern="^/(article\.aspx.*)" />

規則模式

規則模式是用來指定規則輸入字串應該比對的專案。 規則輸入會根據規則組態而有所不同:

  • 如果規則使用標籤篩選,則會傳遞相符標記的內容做為模式比對的輸入。
  • 如果規則未使用任何標籤篩選,則會將整個響應內容當做模式比對的輸入來傳遞。

模式是在重寫規則的相符>專案內<指定。

完整回應模式比對

rule 的 match 元素中未指定 filterByTags 屬性時,將會在整個響應內容上套用模式。 評估整個響應內容上的正則表示式模式是需要大量 CPU 的作業,而且可能會影響 Web 應用程式的效能。 有數個選項可減少完整回應模式比對帶來的效能額外負荷:

  • 使用 IIS 使用者模式快取,並將 outboundRules> 元素的 <rewriteBeforeCache 屬性設定為 true:

    <outboundRules rewriteBeforeCache="true">
    

    請注意,如果區塊傳輸編碼用於回應,則不應該使用此設定。

  • 使用規則之 match 元素的 occurrences 屬性。 例如,當您使用規則將某些 HTML 片段插入 head 元素,<而該規則具有搜尋結尾標籤 - </head> 的模式時,您可以設定 occurrences=“>1”。 這會告訴重寫模組在找到 /head> 標記之後<停止搜尋回應的其餘部分。

    <match pattern="&lt;/head&gt;" occurrences="1" />
    

規則模式語法

您可以使用規則的 patternSyntax 屬性來指定規則模式語法。 這個屬性可以設定為下列其中一個選項:

ECMAScript – Perl 相容 (ECMAScript 標準相容) 正則表示式語法。 這是任何規則的預設選項。 這是模式格式的範例:“^([_0-9a-zA-Z-]+/)?(wp-.*)”

通配符 – IIS HTTP 重新導向模組中使用的通配符語法。 這是此格式模式的範例:「Scripts/*.js」,其中星號 (“*”) 表示「比對任意數目的任何字元,並在反向參考中擷取它們」。 請注意,規則沒有任何標籤篩選時,無法使用通配符模式類型。

ExactMatch - 在輸入字串內執行確切的字串搜尋。

patternSyntax 屬性的範圍是每個規則,這表示它會套用至目前規則的模式,以及該規則條件內使用的所有模式。

規則模式屬性

模式可以使用 match> 元素的<否定屬性來否定。 使用此屬性時,只有在輸入字串不符合指定的模式時,才會執行規則動作。

根據預設,會使用不區分大小寫的模式比對。 若要啟用區分大小寫,您可以使用規則相符>專案的 ignoreCase 屬性<。

規則條件

規則條件允許定義規則評估的其他邏輯,此邏輯可以依據目前輸入字串以外的輸入。 任何規則都可以有零個或多個條件。 規則條件會在規則模式比對成功之後進行評估。

條件定義於重寫規則的條件集合內<>。 此集合具有稱為 logicalGrouping 的屬性,可控制條件的評估方式。 如果規則有條件,則只有在符合規則模式且:

  • 所有條件都評估為 true,前提是已使用logicalGrouping=“MatchAll”。
  • 如果 已使用logicalGrouping=“MatchAny” ,則至少有一個條件評估為 true。

條件是藉由指定下列屬性來定義:

  • 輸入字串 - 條件輸入會指定要作為條件評估輸入的專案。 條件輸入是任意字串,可包含伺服器變數和先前條件模式和/或規則模式的反向參考。

  • 模式 – 在條件輸入中尋找的模式。 您可以使用正規表示式語法或使用通配符語法來指定模式。 在條件中使用的模式類型取決於針對此條件所屬規則所定義的 patternSyntax 旗標值。 此條件類型有兩個控制模式比對的相關屬性:

    • pattern – 使用這個屬性來指定實際的模式。
    • ignoreCase – 使用這個屬性來控制條件的模式比對是否應該區分大小寫或區分大小寫。

規則動作

當輸入字串符合規則模式且條件評估成功時,就會執行重寫規則動作(視規則組態而定,符合所有條件或符合任何一或多個條件)。 有兩種類型的動作可用,而且動作>組態專案的 「type」 屬性<可用來指定規則必須執行的動作。 下列各節說明與特定動作類型相關的不同動作類型和組態選項。

重寫動作

重寫動作會將目前的規則輸入字串取代為替代字串。 替代字串是在規則動作>專案的 value 屬性<內指定。 替代字串是一個自由格式字串,可包含下列專案:

  • 條件和規則模式的回溯參考。 (如需詳細資訊,請參閱如何使用反向參考一節。
  • 伺服器變數。 (如需詳細資訊,請參閱如何使用伺服器變數一節。

無動作

未使用任何動作來指定不應執行任何動作。

從重寫規則存取回應標頭

任何回應 HTTP 標頭的內容都可以從重寫規則內取得,方法是使用與存取伺服器變數相同的語法,但具有特殊的命名慣例。 如果伺服器變數開頭為 「RESPONSE_」,則會儲存 HTTP 回應標頭的內容,其名稱是使用下列命名慣例來決定:

  1. 名稱中的所有底線 (“_”) 符號都會轉換成虛線符號 (“-” )。
  2. 已移除 「RESPONSE_」 前置詞

例如,下列前置條件可用來評估內容類型標頭的內容

<preCondition name="IsHTML">
    <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>

設定要求標頭和伺服器變數

URL Rewrite Module 2.0 中的輸入重寫規則可用來設定要求標頭和伺服器變數。

允許的伺服器變數清單

全域重寫規則可用來設定任何要求標頭和伺服器變數,以及覆寫任何現有的要求標頭。 分散式重寫規則只能設定/覆寫伺服器變數允許的伺服器變數允許伺服器>變數清單中定義的要求標頭和伺服器變數<。 如果分散式重寫規則嘗試設定任何伺服器變數或未列在allowedServerVariables>集合中的 <HTTP 標頭,則 URL Rewrite Module 會產生運行時錯誤。 <allowedServerVariables> 集合預設會儲存在 applicationHost.config 檔案中,而且只能由 IIS 伺服器管理員修改。

使用輸入重寫規則來設定要求標頭和伺服器變數

規則元素 <serverVariables> 可用來定義要設定的伺服器變數和 HTTP 標頭集合。 只有在規則模式相符且條件評估成功時才會設定這些設定(視規則組態而定,符合所有條件或任何一或多個相符的條件)。 serverVariables> 集合中的每個<專案都包含下列各項:

  • Name - 指定要設定的伺服器變數名稱。

  • Value - 指定伺服器變數的值。 值是自由格式字串,可包含:

    • 條件和規則模式的回溯參考。 (如需詳細資訊,請參閱如何使用反向參考一節。
    • 伺服器變數。 (如需詳細資訊,請參閱如何使用伺服器變數一節。
  • 取代 旗標 - 指定如果伺服器變數已經存在,是否要覆寫伺服器變數的值。 默認會啟用取代功能。

下列範例規則會重寫要求的 URL,並設定名稱為 X_REQUESTED_URL_PATH的伺服器變數:

<rule name="Rewrite to index.php" stopProcessing="true">
    <match url="(.*)\.htm$" />
    <serverVariables>
        <set name="X_REQUESTED_URL_PATH" value="{R:1}" />
    </serverVariables>
    <action type="Rewrite" url="index.php?path={R:1}" />
</rule>

注意:若要讓上述範例能夠運作,則需要將X_REQUESTED_URL_PATH新增至 <allowedServerVariables> 集合:

<rewrite>
    <allowedServerVariables>
        <add name="X_REQUESTED_URL_PATH" />
    </allowedServerVariables>
</rewrite>

關於要求標頭的注意事項

要求標頭是使用與伺服器變數相同的機制來設定,但具有特殊的命名慣例。 如果 serverVariables> 集合中的<伺服器變數名稱開頭為 「HTTP_」,這會導致 HTTP 要求標頭根據下列命名慣例進行設定:

  1. 名稱中的所有底線 (“_”) 符號都會轉換成虛線符號 (“-” )。
  2. 所有字母都會轉換成小寫。
  3. 已移除 「HTTP_」 前置詞

例如,下列組態可用來設定要求的自定義 x-original-host 標頭:

<set name="HTTP_X_ORIGINAL_HOST" value="{HTTP_HOST}" />

設定回應標頭

URL Rewrite Module 2.0 中的輸出重寫規則可用來設定新的或修改現有的回應 HTTP 標頭。 回應 HTTP 標頭會使用與伺服器變數相同的語法,並使用從重寫規則存取回應標頭中所述的命名慣例,在輸出規則中存取 HTTP 標頭。

如果輸出重寫規則之 match> 元素的 <serverVariable 屬性具有值,則表示此重寫規則會在對應回應標頭的內容上運作。 例如,下列規則會設定回應標頭 「x-custom-header」:

<outboundRules>
    <rule name="Set Custom Header">
        <match serverVariable="RESPONSE_X_Custom_Header" pattern="^$" />
        <action type="Rewrite" value="Something" />
    </rule>
</outboundRules>

重寫規則的模式將會套用在指定回應標頭的內容上,如果規則的模式和選擇性條件評估成功,則會重寫該響應標頭的值。

正則表達式模式和輕鬆存取重寫規則中現有的要求和回應標頭,在定義重寫回應 HTTP 標頭的邏輯時,提供許多彈性。 例如,下列重寫規則可用來修改重新導向回應中Location標頭的內容:

<outboundRules>
    <!-- This rule changes the domain in the HTTP location header for redirection responses -->
    <rule name="Change Location Header">
        <match serverVariable="RESPONSE_LOCATION" pattern="^http://[^/]+/(.*)" />
        <conditions>
            <add input="{RESPONSE_STATUS}" pattern="^301" />
        </conditions>
        <action type="Rewrite" value="http://{HTTP_HOST}/{R:1}"/>
    </rule>
</outboundRules>

在重寫規則中使用反向參考

規則或條件輸入的部分可以在反向參考中擷取。 然後,這些可用來在規則動作內建構替代 URL,或建構規則條件的輸入字串。

背參考會以不同的方式產生,視規則使用哪種模式語法而定。 使用ECMAScript模式語法時,可以藉由將括弧放在必須擷取反向參考之模式的一部分來建立反向參考。 例如,模式 ([0-9]+)/([a-z]+).html會從此字串擷取 07文章:07/article.html。 使用「通配符」模式語法時,在模式中使用星號符號 \ 時,一律會建立反向參考。

不論使用哪一種模式語法來擷取它們,反向參考的使用方式都相同。 回溯參考可用於重寫規則內的下列位置:

  • 在條件輸入字串中

  • 在規則動作中,具體來說:

    • 輸入規則中重寫和重新導向動作的url屬性
    • 輸出規則中重寫動作的 value 屬性
    • CustomResponse 動作的 statusLine 和 responseLine
  • 在重寫對應的關鍵參數中

條件模式的反向參考是由 {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="Back-references with trackAllCaptures set to false">
 <match url="^article\.aspx" >
 <conditions>
    <add input="{QUERY_STRING}" pattern="p1=([0-9]+)" />
    <add input="{QUERY_STRING}" pattern="p2=([a-z]+)" />  
 </conditions>
 <action type="Rewrite" url="article.aspx/{C:1}" /> <!-- rewrite action uses back-references to the last matched condition -->
</rule>

反向參考 {C:1} 一律會包含第二個條件中擷取群組的值,這會是查詢字元串參數 p2 的值。 p1 的值將無法作為反向參考使用。

在 URL 重寫模組 2.0 中,您可以變更擷取群組的編制索引方式。 在條件集合上<啟用 trackAllCaptures 設定可讓擷取群組形成所有相符條件,以便透過>反向參考使用。 例如,在此規則中:

<rule name="Back-references with trackAllCaptures set to true">
 <match url="^article\.aspx" >
 <conditions trackAllCaptures="true">
    <add input="{QUERY_STRING}" pattern="p1=([0-9]+)" />
    <add input="{QUERY_STRING}" pattern="p2=([a-z]+)" />  
 </conditions>
 <action type="Rewrite" url="article.aspx/{C:1}/{C:2}" /> <!-- rewrite action uses back-references to both conditions -->
</rule>

反向參考 {C:1} 會包含第一個條件中的擷取群組值,而反向參考 {C:2} 會包含第二個條件中的擷取群組值。

當 trackAllCaptures 設定為 true 時,條件擷取反向參考會由 {C:N} 識別,其中 N 從 0 到所有規則條件中的擷取群組總數。 {C:0} 包含來自第一個相符條件的整個相符字串。 例如,這兩個條件:

<conditions trackAllCaptures="true">
    <add input="{REQUEST_URI}" pattern="^/([a-zA-Z]+)/([0-9]+)/$" />
    <add input="{QUERY_STRING}" pattern="p2=([a-z]+)" />  
 </conditions>

如果 {REQUEST_URI} 包含 “/article/23/” 且 {QUERY_STRING} 包含 “p1=123&p2=abc”,則會編製條件反向參考的索引,如下所示:

{C:0} - “/article/23/”
{C:1} - “article”
{C:2} - “23”
{C:3} - “abc”

將重寫 URL 記錄到 IIS 記錄

分散式輸入重寫規則可以設定為將重寫 URL 記錄到 IIS 記錄檔,而不是記錄 HTTP 用戶端所要求的原始 URL。 若要啟用重寫 URL 的記錄,請使用規則動作>元素的 <logRewrittenUrl 屬性,例如:

<rule name="set server variables">
    <match url="^article/(\d+)$" />
    <action type="Rewrite" url="article.aspx?id={R:1}" logRewrittenUrl="true" />
</rule>