作者 :魯斯蘭·雅庫舍夫
本教學將說明 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 字串來評估分散式規則集。
先決條件
此操作指南需要具備以下條件:
- IIS 7.0 或以上版本,啟用 ASP.NET 角色服務
- URL 重寫的 Go Live 版本已安裝
設置演練場景
為了示範如何使用全域與本地規則,我們將實作一個常見的情境:將子網域映射到目錄。 這將允許我們使用子網域存取網站上不同目錄中的內容。 例如,使用者可以瀏覽到 http://blog.mysite.com 而非 http://mysite.com/blog,或瀏覽到 http://forum.mysite.com 而非 http://mysite.com/forum。
要設定情境,請執行以下步驟:
在資料夾裡建立兩個資料夾,分別叫做「blog」和「forum」。
%SystemDrive%\inetpub\wwwroot\複製以下 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>複製以下 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>打開名為「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 建立全域規則,請遵循以下步驟:
現在我們必須定義實際的重寫規則。 在 URL 重寫模組中,重寫規則的定義是透過指定四個基本資訊:
- 規則的名稱
- 用於匹配 URL 字串的模式
- 可選條件
- 若模式匹配且所有條件檢定成功,執行動作
規則命名
在「名稱」文字框中輸入一個能唯一識別規則的名稱,例如:「子網域映射」。
定義模式
在「Pattern」文字框中輸入以下字串:
(.*)
此字串是一個正則表達式,指定該模式會匹配任何 URL 字串,包括空字串,並會以回溯參考方式捕捉匹配的字串。
定義條件
點擊「新增條件」按鈕:
點擊「新增...」按鈕用來開啟定義條件的對話框。
對於「條件輸入:」輸入此字串:「{HTTP_HOST}」。 此時會將 URL 重寫模組設定為使用 HTTP 請求主機標頭的值作為條件的輸入
在下拉選單的連擊框中選擇「符合圖案」。
在「圖案」文字框輸入「^([^_]+)_[^_]+」。 這個正則表達式會用來匹配我們建立的領域(blog_localhost 和 forum_localhost),並會將字串中「_」符號前的部分擷取成回向參考。 例如對於字串「blog_localhost」,它會保留「blog」在回溯參考中。
在所有屬性都指定完成後,條件對話框應如下所示:
點擊確定以儲存條件,然後返回「新增規則」介面。
定義動作
由於我們所建立的規則是要重寫 URL,請在「動作」群組框中選擇「重寫」動作類型。 在「重寫網址:」文字框中輸入以下字串:
{C:1}/{R:1}
此字串指定輸入 URL 應重寫為何處。 條件 {C:1} 的後向參考用作資料夾名稱,然後透過規則 {R:1} 的後向參考保留在規則模式中擷取的內容。
其他設定則保留預設值。 「編輯規則」介面應該看起來像以下頁面:
點擊右側的「套用」動作儲存規則。
為了了解此規則的應用方式,讓我們先了解當 HTTP 客戶端請求此 URL 時,URL 重寫模組執行的步驟:
http://blog_localhost/article.aspx?id=323:
- URL 重寫模組會將 "article.aspx?id=323" 作為規則的輸入 URL,成功與規則範本匹配,並將其捕捉到規則回溯參考 {R:1}。
- 主機標頭值(「blog_localhost」)成功匹配正則表達式「^([^_]+)_[^_]+」,因此「blog」被捕獲並作為條件回溯引用 {C:1}。
- 依照替換字串 {C:1}/{R:1},網址會重寫為「blog/article.aspx?id=323」。
測試規則
為了測試規則是否正確重寫網址,請開啟網頁瀏覽器並請求以下網址:
http://blog_localhost/article.aspx?id=123
你應該會看到 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 檔案來建立規則。
要建立分散式重寫規則:
在資料夾裡
%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}&title={R:2}"/> </rule> </rules> </rewrite> </system.webServer> </configuration>在資料夾裡
%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}&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」。
總結
在這個教學中,你透過全域規則實作了一個子網域映射場景,然後用分散式規則讓這些資料夾中的網頁能使用使用者友善的網址。