本文補充了mod_rewrite
參考。它描述了使用mod_rewrite
所必需的基本概念。其他檔案更詳細,但這個文件應該有助於初學者弄濕Apache中的重寫。
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由三個以空格分隔的引數組成,它們分別是 -
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"