本文補充了mod_rewrite參考。它描述了使用mod_rewrite所必需的基本概念。其他檔更詳細,但這個文檔應該有助於初學者弄濕Apache中的重寫。
Apache URL重寫介紹
Apache模組mod_rewrite是一個非常強大和複雜的模組,它提供了一種進行URL操作的方法。有了它,您幾乎可以進行所需的所有類型的URL重寫。但是它有點複雜,並且可能對初學者來說是令人生畏的。
本文試圖提供足夠的背景知識,以便理解後面的內容,而不是盲目地複製。
請記住,許多常見的URL操作任務不需要mod_rewrite的全部功能和複雜性。有關簡單任務,請參閱mod_alias以及有關將URL映射到檔系統的文檔。
最後,在繼續之前,請確保使用LogLevel指令將mod_rewrite的日誌級別配置為其中一個跟蹤級別。雖然這可以提供大量的資訊,但它在調試mod_rewrite配置問題時是必不可少的,因為它會告訴您每個規則的處理方式。
正則運算式
mod_rewrite使用Perl相容的正則運算式辭彙表。在本文檔中,我們不會嘗試提供正則運算式的詳細參考。推薦由Jeffrey Friedl撰寫的PCRE手冊頁,Perl正則運算式手冊頁和精通正則運算式。
正則運算式辭彙
以下是最小構建塊,以便編寫正則運算式和RewriteRules。它們當然不代表完整的正則表達辭彙,但它們是一個很好的起點,應該幫助您閱讀基本的正則運算式,以及編寫自己的正則運算式。
| 字元 | 含意 | 示例 |
|---|---|---|
. |
匹配任何單個字元 | c.t可匹配cat, cot 和 cut等。 |
+ |
重複上一個匹配一次或多次 | a+匹配a,aa,aaa等。 |
* |
重複前一個匹配零次或多次。 | a*匹配a+匹配的所有相同內容,但也匹配空字元串。 |
? |
使匹配可選。 | colou?r匹配 color 和 colour |
^ |
稱為錨點,匹配字串的開頭。 | ^a匹配以a開頭的字串 |
$ |
另一個錨點,它匹配字串的結尾。 | a$匹配以a結尾的字串。 |
( ) |
將多個字元組合到一個單元中,並捕獲匹配以用於反向引用。 | (ab)+ 匹配ababab - 也就是說,+適用於組。 |
[ ] |
字元類 - 匹配其中一個字元。 | c[uoa]t 匹配 cut, cot 或者 cat。 |
[^ ] |
負字元類 - 匹配未指定的任何字元。 | c[^/]t 匹配 cat或 c=t,但是不匹配c/t。 |
正則運算式反向引用可用性
這裏必須記住一件重要的事情:無論何時在Pattern或其中一個CondPattern中使用括弧,都會在內部創建後引用,它可以與字串$N和%N一起使用(見下文)。這些可用於創建RewriteRule的Substitution參數或RewriteCond的TestString參數。
RewriteRule模式中的捕獲(反直覺地)可用於所有前面的RewriteCond指令,因為RewriteRule運算式在各個條件之前被計算。
下圖顯示了後向引用轉移到哪些位置以進行擴展,以及說明RewriteRule,RewriteCond匹配的流程。在接下來的章節中,我們將探索如何使用這些反向引用,所以不要擔心。

在此示例中,/test/1234的請求將轉換為/admin.foo?page=test&id=1234&host=admin.example.com。
RewriteRule基礎
RewriteRule由三個以空格分隔的參數組成,它們分別是 -
Pattern:傳入的URL應受規則影響;Substitution:匹配請求應在何處發送;[flags]:影響重寫請求的選項。
Pattern是一個正則運算式。它最初(對於第一個重寫規則或直到發生替換)與傳入請求的URL路徑(主機名之後但在任何指示查詢字串開頭的問號之前)或者在每個目錄中匹配上下文,針對相對於定義規則的目錄的請求路徑。一旦發生替換,後面的規則將與替換值進行匹配。

Substitution 有三種表達格式:
資源的完整檔系統路徑
RewriteRule "^/games" "/usr/local/games/web"這會將請求映射到檔系統上的任意位置,就像
Alias指令一樣。資源的Web路徑
RewriteRule "^/foo$" "/bar"如果
DocumentRoot設置為/usr/local/apache2/htdocs,則此指令會將對http://example.com/foo的請求映射到路徑/usr/local/apache2/htdocs/bar。絕對URL
RewriteRule "^/product/view$" "http://site2.example.com/seeproduct.html" [R]這告訴客戶端為指定的URL發出新請求。
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等中按順序可用。
重寫標誌
可以通過在規則末尾應用一個或多個標誌來修改RewriteRule的行為。例如,通過應用[NC]標誌,可以使規則的匹配行為不區分大小寫:
RewriteRule "^puppy.html" "smalldog.html" [NC]
重寫條件
可以使用一個或多個RewriteCond指令來限制將受以下RewriteRule約束的請求類型。第一個參數是描述請求特徵的變數,第二個參數是必須與變數匹配的正則運算式,第三個可選參數是修改匹配評估方式的標誌列表。

例如,要將來自特定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時才應用該規則。
RewriteConds中包含的正則運算式中的匹配項可以使用變數%1,%2等作為RewriteRule中的替換的一部分。例如,這將根據用於訪問的主機名將請求定向到其他目錄網站:
RewriteCond "%{HTTP_HOST}" "(.*)"
RewriteRule "^/(.*)" "/sites/%1/$1"
