<-
Apache > HTTP 伺服器 > 文件 > 版本 2.4 > Rewriter

Apache mod_rewrite 簡介

可用的語言:  en  |  fr 

此文件補充 mod_rewrite 參考文件。它說明使用 mod_rewrite 所需的基本概念。其他文件會深入說明,但此文件應有助初學者入門。

Support Apache!

另請參閱

top

簡介

Apache 模組 mod_rewrite 是一個非常強大且複雜的模組,提供了執行網址操作的方法。使用它,您可以執行幾乎所有您需要的網址改寫。然而,它有點複雜,初學者可能會感到害怕。此外,也常將改寫規則視為一種魔法咒語,在不了解其作用的情況下使用它們。

本文檔嘗試提供充分的背景說明,讓後續內容易於理解,不會只是盲目複製。

請記住,許多常見的網址操作工作並不需要 mod_rewrite 的所有功能和複雜性。對於簡單的工作,請參閱 mod_alias 和關於 將網址對應到檔案系統 的文件。

最後,在繼續後續操作之前,請務必使用 LogLevel 指令將 mod_rewrite 的日誌層級設定為其中一個追蹤層級。雖然這可能會提供大量的資訊,但它對於偵錯 mod_rewrite 設定的問題是不可或缺的,因為它會告訴您每個規則是如何處理的。

top

正規表示式

mod_rewrite 使用 Perl 相容正規表示法 語彙。
在此文件中,我們不提供正規表示法的詳細參考。對於細節,我們推薦 PCRE 手冊頁面Perl 正規表示法手冊頁面,以及 Jeffrey Friedl 撰寫的 Mastering Regular Expressions

在此文件中,我們提供足夠的 regex 語彙,讓您快速上手,而不會不知所措,希望 RewriteRules 具有科學公式,而不是魔咒咒語。

Regex 語彙

以下是撰寫正規表示法和 RewriteRule 所需的基本構件。它們肯定無法表示完整的正規表示法語彙,但這是個起點,應該能幫助您閱讀基本正規表示法,以及撰寫您自己的正規表示法。

字元 意義 範例
. 與任何單一字元相符 c.t 將與 catcotcut 等相符
+ 重複前一次相符項一次或多次 a+aaaaaa 等相符
* 重複前一次相符項零次或多次 a*a+ 相符項相同,但也會與空字串相符
? 使相符項為選擇性 colou?r 將與 colorcolour 相符
\ 轉譯下一個字元 \. 將與 .(點)相符,而不是如上說明的 任何單一字元
^ 稱為錨點,與字串開頭相符 ^a 與以 a 開頭的字串相符
$ 另一個錨點,與字串結尾相符 a$ 與以 a 結尾的字串相符
( ) 將多個字元分組為單一單位,並捕獲相符項以供反向參照使用 (ab)+ababab 相符 - 也就是說,+ 適用於群組。有關反向參照的詳細資訊,請參閱 以下內容
[ ] 一個字元類別 - 與其中一個字元相符 c[uoa]tcutcotcat 相符
[^ ] 負向字元類別 - 與未指定的任何字元相符 c[^/]tcatc=t 相符,但與 c/t 不相符

mod_rewrite 中,! 字元可以用於正規表示法之前,以否定它。也就是說,當且僅當字串與表示法的其他部分不相符時,才視為已相符。

Regex 反向參照可用性

這裏有一件重要的事必須記住:無論你什麼時候在 Pattern 或是 CondPattern 中使用括號,系統都會建立內部的反向參照,可用於字串 $N%N (見下文)。這些可供建立 RewriteRuleSubstitution 參數或是 RewriteCondTestString 參數。

RewriteRule 模式中的捕獲(反直覺地)可用於所有前置的 RewriteCond 指令,因為 RewriteRule 表達式在個條件之前評估。

圖 1 呈現了反向參照展開的位置以及說明 RewriteRule、RewriteCond 配對的流程。在接下來的章節中,我們將探索如何使用這些反向參照,所以如果你一開始有點陌生,不用煩惱。

Flow of RewriteRule and RewriteCond matching
圖 1: 反向參照經由規則擴充。
在這個範例中,對 /test/1234 的請求會轉換成 /admin.foo?page=test&id=1234&host=admin.example.com

top

RewriteRule 基本知識

RewriteRule 包含三個參數,以空格分隔。這些參數是

  1. Pattern:哪些輸入 URL 應受規則影響;
  2. Substitution:配對的請求應傳送到哪裡;
  3. [flags]:影響已改寫請求的選項。

Pattern正規表示法。最初(針對第一條改寫規則或在替換發生之前)與輸入請求的 URL 路徑配對(主機名稱之後且在疑問號之前標示查詢字串開始的任何部分),或在每個目錄的脈絡下與請求相對於規則所定義的目錄的路徑進行配對。一旦替換發生,後續規則將與替換值配對。

Syntax of the RewriteRule directive
圖 2: RewriteRule 指令的語法。

Substitution 本身可以是三件事中的其中一件事

1. 檔案系統路徑
RewriteRule "^/games" "/usr/local/games/web/puzzles.html"

這會將請求對應到檔案系統上的任意位置,很像 Alias 指令。

2. 網路路徑
RewriteRule "^/games$" "/puzzles.html"

如果 DocumentRoot 設定為 /usr/local/apache2/htdocs,那麼這個指令將對 http://example.com/games 的請求對應到路徑 /usr/local/apache2/htdocs/puzzles.html

3. 絕對 URL
RewriteRule "^/product/view$" "http://site2.example.com/seeproduct.html" [R]

這告訴客戶端建立指定 URL 的新請求。

請注意,12 具有完全相同的語法。兩者之間的差異在於,**1** 的目標路徑頂層(即 /usr/)存在於檔案系統中,而 2 則不存在。(即檔案系統中沒有 /bar/ 作為根目錄。)

Substitution 也可包含往後參照Pattern 匹配的,來自於輸入 URL 路徑的部份。考慮下列範例

RewriteRule "^/product/(.*)/view$" "/var/web/productdb/$1"

變數 $1 會替換掉 Pattern 中括弧內表達式所匹配的文字。例如,針對 http://example.com/product/r14df/view 的請求會對應到路徑 /var/web/productdb/r14df

若括弧裡有以上一個以上的表達式,它們會依序在變數 $1$2$3 等中使用。

top

重寫旗標

RewriteRule 的行為會隨著規則最後的其中一個或多個旗標應用而被修改。例如,規則的配對行為可透過應用 [NC] 記號來調整大小寫不敏感

RewriteRule "^puppy.html" "smalldog.html" [NC]

有關可用旗標、其意義和範例的更多詳細資訊,請參閱 重寫旗標 文件。

top

重寫條件

一個或多個 RewriteCond 指示條件可被用來限制類型的請求,而接下來的 RewriteRule 會針對這些請求進行判斷。第一個參數是一個描述請求特性的變數,第二個參數是一個必須與該變數配對的 正規表示法,第三個可選參數是一個旗標清單,用來修改匹配的評估方式。

Syntax of the RewriteCond directive
圖 3: RewriteCond 指示條件的語法

例如,若要將來自特定 IP 範圍的所有請求都導向到另一部伺服器,可以使用

RewriteCond "%{REMOTE_ADDR}" "^10\.2\."
RewriteRule "(.*)"           "http://intranet.example.com$1"

若指定了一個以上的 RewriteCond,則在套用 RewriteRule 之前,必須全部與之匹配。例如,若要拒絕查詢字串中包含「hack」字樣的請求,除非其也包含一個含有「go」字樣的 Cookie,可以使用

RewriteCond "%{QUERY_STRING}" "hack"
RewriteCond "%{HTTP_COOKIE}"  !go
RewriteRule "."               "-"   [F]

請注意,感嘆號指定一個否定匹配,因此僅在 Cookie 不包含「go」的情況下,才會套用這個規則。

包含在 RewriteCond 中的正規表示法中找到的匹配,可用於 RewriteRuleSubstitution 的一部份,使用變數 %1%2 等等。例如,這個範例會根據用來存取網站的主機名稱將請求導向不同的目錄

RewriteCond "%{HTTP_HOST}" "(.*)"
RewriteRule "^/(.*)"       "/sites/%1/$1"

如果請求是 http://example.com/foo/bar,那麼 %1 會包含 example.com$1 會包含 foo/bar

top

重寫對應

RewriteMap 指令提供了一個呼叫外部函式的途徑,也就是為你改寫你的重寫。這將在 RewriteMap 補充說明 中進行更詳細的討論。

top

.htaccess 檔案

重寫通常在主伺服器組態設定 (在任何 <Directory> 區段之外) 或在 <VirtualHost> 容器中組態。這是執行重寫最簡單的方式,建議使用此方式。然而,在 <Directory> 區段或 .htaccess 檔案 中執行重寫也是可能的,但會帶來一些額外的複雜性。此技術稱為目錄重寫。

與伺服器重寫的主要差異在於,在 RewriteRule 中進行比對之前,包含 .htaccess 檔案的目錄路徑前綴會被移除。此外,應使用 RewriteBase 來確保請求正確對應到映射。

可用的語言:  en  |  fr 

top

評論

注意事項
這不是問答區。放置在這裡的評論應指向改進說明文件或伺服器的建議,如果這些評論已實作或被視為無效/離題,則可能會被我們的管理員移除。關於如何管理 Apache HTTP Server 的問題應導向我們的 IRC 頻道,#httpd,在 Libera.chat,或寄送至我們的 郵件清單