Apache URL重寫入門

2019-10-16 22:02:05

本文補充了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, cotcut等。
+ 重複上一個匹配一次或多次 a+匹配aaaaaa等。
* 重複前一個匹配零次或多次。 a*匹配a+匹配的所有相同內容,但也匹配空字串。
? 使匹配可選。 colou?r匹配 colorcolour
^ 稱為錨點,匹配字串的開頭。 ^a匹配以a開頭的字串
$ 另一個錨點,它匹配字串的結尾。 a$匹配以a結尾的字串。
( ) 將多個字元組合到一個單元中,並捕獲匹配以用於反向參照。 (ab)+ 匹配ababab - 也就是說,+適用於組。
[ ] 字元類 - 匹配其中一個字元。 c[uoa]t 匹配 cut, cot 或者 cat
[^ ] 負字元類 - 匹配未指定的任何字元。 c[^/]t 匹配 catc=t,但是不匹配c/t

正規表示式反向參照可用性

這裡必須記住一件重要的事情:無論何時在Pattern或其中一個CondPattern中使用括號,都會在內部建立後參照,它可以與字串$N%N一起使用(見下文)。這些可用於建立RewriteRuleSubstitution引數或RewriteCondTestString引數。

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路徑(主機名之後但在任何指示查詢字串開頭的問號之前)或者在每個目錄中匹配上下文,針對相對於定義規則的目錄的請求路徑。一旦發生替換,後面的規則將與替換值進行匹配。

Pattern

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"