使用全域與分散式重寫規則

作者 :魯斯蘭·雅庫舍夫

本教學將說明 URL 重寫模組支援的不同規則類型,並引導你如何配置全域與分散式重寫規則。

背景

全域重寫規則用於定義伺服器範圍的 URL 重寫邏輯。 這些規則在 applicationHost.config 檔案中定義,且無法在較低的設定層級(如網站或虛擬目錄)上覆寫或停用。 全域規則總是在絕對 URL 路徑上運作(即請求的 URI,但沒有伺服器名稱)。 例如,若向 http://localhost/directory1/directory2/index.html 發送請求,URL 重寫模組會將「directory1/directory2/index.html」作為一項全域規則的輸入。

分散式重寫規則用於定義特定配置範圍的 URL 重寫邏輯。 分散式規則可透過 web.config 檔案在任何設定層級(檔案除外)定義。 本地規則總是針對相對於 Web.config 檔案位置的 URL 來運作。 例如,如果對目錄1的檔案 Web.config http://localhost/directory1/directory2/index.html 提出請求並定義重寫規則,則 URL 重寫模組會將「directory2/index.html」作為該規則的輸入。

全域規則集總是先被評估,之後再使用全域規則集產生的 URL 字串來評估分散式規則集。

先決條件

此操作指南需要具備以下條件:

  1. IIS 7.0 或以上版本,啟用 ASP.NET 角色服務
  2. URL 重寫的 Go Live 版本已安裝

設置演練場景

為了示範如何使用全域與本地規則,我們將實作一個常見的情境:將子網域映射到目錄。 這將允許我們使用子網域存取網站上不同目錄中的內容。 例如,使用者可以瀏覽到 http://blog.mysite.com 而非 http://mysite.com/blog,或瀏覽到 http://forum.mysite.com 而非 http://mysite.com/forum。

要設定情境,請執行以下步驟:

  1. 在資料夾裡建立兩個資料夾,分別叫做「blog」和「forum」。%SystemDrive%\inetpub\wwwroot\

  2. 複製以下 asp.net 程式碼,並放入 %SystemDrive%\inetpub\wwwroot\blog 名為 article.aspx 的資料夾中:

    <%@ 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>
          <p>This page is located in blog subdomain.</p>
          <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>
    
  3. 複製以下 asp.net 程式碼,並將其放入 %SystemDrive%\inetpub\wwwroot\forum 名為 forum.aspx 的資料夾中:

    <%@ 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>
          <p>This page is located in forum subdomain.</p>
          <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>
    
  4. 打開名為「hosts」的檔案,位於 , %SystemDrive%\windows\system32\drivers\etc\ 並在其中新增以下兩行:

    127.0.0.1 forum_localhost
    127.0.0.1 blog_localhost
    

    加入這些指令後,打開網路瀏覽器,瀏覽至 http://blog_localhost/blog/article.aspx 及 http://forum_localhost/forum/forum.aspx,確認頁面是否在瀏覽器中正確呈現。

建立全域重寫規則

首先,我們將建立一個全域重寫規則,根據主機標頭重寫 URL。 例如,如果請求是發送至 http://blog_localhost/article.aspx,則規則會將網址路徑更改為「/blog/article.aspx」。

要在 IIS Manager 中使用 URL Rewrite UI 建立全域規則,請遵循以下步驟:

  1. 前往IIS管理員
  2. 在導航樹檢視中選擇伺服器節點。
  3. 在功能檢視中點選「URL 重寫模組」
    WIN 2 K 8 R T M 首頁截圖。U R L Rewrite 圖示會被高亮顯示。
  4. 在「動作」面板中點選「新增規則...」
    U R L 重寫頁面的截圖。在動作面板中,會標示「新增規則」。
  5. 在「新增規則」對話框中,選擇「空白規則」並點選「確定」:
    新增規則對話框的截圖。選取了空白規則圖示。

現在我們必須定義實際的重寫規則。 在 URL 重寫模組中,重寫規則的定義是透過指定四個基本資訊:

  • 規則的名稱
  • 用於匹配 URL 字串的模式
  • 可選條件
  • 若模式匹配且所有條件檢定成功,執行動作

規則命名

在「名稱」文字框中輸入一個能唯一識別規則的名稱,例如:「子網域映射」。

定義模式

在「Pattern」文字框中輸入以下字串:

(.*)

此字串是一個正則表達式,指定該模式會匹配任何 URL 字串,包括空字串,並會以回溯參考方式捕捉匹配的字串。

定義條件

點擊「新增條件」按鈕:

編輯規則頁面的截圖。在條件類別中,會標示「新增條件」。

點擊「新增...」按鈕用來開啟定義條件的對話框。

編輯規則頁面的截圖。條件類別中的新增按鈕會被高亮顯示。
對於「條件輸入:」輸入此字串:「{HTTP_HOST}」。 此時會將 URL 重寫模組設定為使用 HTTP 請求主機標頭的值作為條件的輸入

在下拉選單的連擊框中選擇「符合圖案」。

在「圖案」文字框輸入「^([^_]+)_[^_]+」。 這個正則表達式會用來匹配我們建立的領域(blog_localhost 和 forum_localhost),並會將字串中「_」符號前的部分擷取成回向參考。 例如對於字串「blog_localhost」,它會保留「blog」在回溯參考中。

在所有屬性都指定完成後,條件對話框應如下所示:

編輯條件對話框的截圖。在條件輸入框中,文字[HTTP_HOST]被寫入。已勾選「忽略大小寫」的勾選框。

點擊確定以儲存條件,然後返回「新增規則」介面。

定義動作

由於我們所建立的規則是要重寫 URL,請在「動作」群組框中選擇「重寫」動作類型。 在「重寫網址:」文字框中輸入以下字串:

{C:1}/{R:1}

此字串指定輸入 URL 應重寫為何處。 條件 {C:1} 的後向參考用作資料夾名稱,然後透過規則 {R:1} 的後向參考保留在規則模式中擷取的內容。

其他設定則保留預設值。 「編輯規則」介面應該看起來像以下頁面:

編輯規則頁面的截圖。輸入、類型和模式欄位都有文字。

點擊右側的「套用」動作儲存規則。

為了了解此規則的應用方式,讓我們先了解當 HTTP 客戶端請求此 URL 時,URL 重寫模組執行的步驟:
http://blog_localhost/article.aspx?id=323:

  1. URL 重寫模組會將 "article.aspx?id=323" 作為規則的輸入 URL,成功與規則範本匹配,並將其捕捉到規則回溯參考 {R:1}。
  2. 主機標頭值(「blog_localhost」)成功匹配正則表達式「^([^_]+)_[^_]+」,因此「blog」被捕獲並作為條件回溯引用 {C:1}。
  3. 依照替換字串 {C:1}/{R:1},網址會重寫為「blog/article.aspx?id=323」。

測試規則

為了測試規則是否正確重寫網址,請開啟網頁瀏覽器並請求以下網址:
http://blog_localhost/article.aspx?id=123

U R L 重寫模組測試頁面的截圖。會顯示伺服器變數資訊與值資訊。

你應該會看到 URL 重寫模組已經更改了網址,並在「blog」目錄中開啟了Article.aspx頁面。 URL 重寫模組所做的變更是基於從主機標頭擷取的資訊。

同樣地,當你申請 http://forum_localhost/forum.aspx?id=345 時,網址也會被重寫成 /forum/forum.aspx?id=345。

建立分散式規則

我們剛建立的全域規則是用來根據從主機標頭擷取的資訊,將請求映射到資料夾。 現在我們將建立分散式規則,允許使用 URL 而不使用查詢字串參數。 分散式規則會以已被全域規則修改的 URL 作為輸入,並對其進行額外修改。 特別是:

  • 「blog」資料夾中的重寫規則會將網址路徑從「article/234/some-title」重寫為「article.aspx?id=234&title=some-title」。
  • 在「forum」資料夾中的重寫規則會將網址路徑從「topic/123/some-topic-title」重寫為「forum.aspx?topic=some-topic-title&id=123」。

本地規則可透過使用 IIS Manager 或編輯 web.config 檔案來建立。 為了示範,我們將透過手動編輯 web.config 檔案來建立規則。

要建立分散式重寫規則:

  1. 在資料夾裡 %SystemDrive%\inetpub\wwwroot\**blog** 建立一個空的 web.config 檔案。 在文字編輯器中開啟它,然後貼上以下 XML 程式碼:

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
      <system.webServer>
        <rewrite>
          <rules>
            <rule name="Rewrite to article.aspx">
              <match url="^article/([0-9]+)/([_0-9a-z-]+)"/>
              <action type="Rewrite" url="article.aspx?id={R:1}&amp;title={R:2}"/>
            </rule>
          </rules>
        </rewrite>
      </system.webServer>
    </configuration>
    
  2. 在資料夾裡 %SystemDrive%\inetpub\wwwroot\**forum** 建立一個空的 web.config 檔案。 在文字編輯器中開啟它,然後貼上以下 XML 程式碼:

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
      <system.webServer>
        <rewrite>
          <rules>
            <rule name="Rewrite to forum.aspx">
              <match url="^topic/([0-9]+)/([_0-9a-z-]+)"/>
              <action type="Rewrite" url="forum.aspx?topic={R:2}&amp;id={R:1}"/>
            </rule>
          </rules>
        </rewrite>
      </system.webServer>
    </configuration>
    

測試全域與分散式規則

為了測試所有規則是否能正常運作,打開網頁瀏覽器並向 發出請求。http://blog_localhost/article/234/some-title 瀏覽器回應應顯示該網址先由全域規則更改,接著又被分散式規則修改。

同樣地,如果你請求 http://forum_localhost/topic/123/some-topic-title,你應該會看到 URL 重寫模組會將請求的 URL 字串改為「/forum/forum.aspx?topic=some-topic-title&id=123」。

U R L 重寫模組測試頁面的截圖。U R 線已經改變。

總結

在這個教學中,你透過全域規則實作了一個子網域映射場景,然後用分散式規則讓這些資料夾中的網頁能使用使用者友善的網址。