Apache Rewrite詳解

tusi發表於2019-02-16

Rewrite的需求

在用Apache做web伺服器的時候,有的時候需要將輸入的URL轉換成另一個URL這種需求。比如用CodeIgniter框架開發web應用的時候,我們訪問的所有路徑都要經過index.php,由這個index.php做統一路由,訪問地址如下:

example.com/index.php/news/article/my_article

每次訪問都帶著index.php,實在太多餘了,我們想要一個乾淨的地址如下:

example.com/news/article/my_article

這時你的 Apache 伺服器需要啟用mod_rewrite,然後簡單的通過一個 .htaccess 檔案再加上一些簡單的規則就可以移除URL中的 index.php 了。下面是這個檔案的一個例子, 其中使用了 “否定條件” 來排除某些不需要重定向的專案:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]

在上面的例子中,除已存在的目錄和檔案,其他的 HTTP 請求都會經過你的 index.php 檔案。也就是說單使用者在位址列裡輸入【example.com/news/article/my_article】的時候實際上訪問的是【example.com/index.php/news/article/my_article】。

Rewrite使用詳解

 確認Apache是否載入了Rewrite模組

Apache2.x

LoadModule rewrite_module modules/mod_rewrite.so

啟用.htaccess
AllowOverride None 修改為: AllowOverride All

RewriteCond 與 RewriteRule

學習Rewrite需要重點了解它的三個核心:RewriteEngine,RewriteCond,RewriteRule。

RewriteEngine

這個是rewrite功能的總開關,用來開啟是否啟動url rewrite

RewriteEngine on

RewriteCond

RewriteCond就是一個過濾條件,簡單來說,當URL滿足RewriteCond配置的條件的情況,就會執行RewriteCond下面緊鄰的RewriteRule語句。

RewriteCond的格式如下:
RewriteCond %{NAME_OF_VARIABLE} REGX FLAG

舉個例子:

RewriteEngine on
RewriteCond  %{HTTP_USER_AGENT}  ^Mozilla//5/.0.*
RewriteRule  index.php            index.m.php

如果設定上面的匹配規則,到來的http請求頭中的HTTP_USER_AGENT匹配【^Mozilla//5/.0.*】正規表示式的話,則執行下面的RewriteRule,也就是說訪問路徑會跳轉到 index.m.php這個檔案。

RewriteCond 和 RewriteRule 是上下對應的關係。可以有1個或者好幾個RewriteCond來匹配一個RewriteRule

那麼RewriteCond可以匹配什麼樣的資料請求呢?

RewriteCond %{HTTP_REFERER} (www.test.cn)
RewriteCond %{HTTP_USER_AGENT}  ^Mozilla//5/.0.*
RewriteCond %{REQUEST_FILENAME} !-f

上面是常見的3種最常見使用最多的HTTP頭連線與請求匹配。

  • HTTP_REFERER 當前請求頁面的來源頁面的地址
  • 當前請求頭中 User-Agent: 項的內容,如果存在的話。該字串表明了訪問該頁面的使用者代理的資訊。一個典型的例子是:Mozilla/5.0 (Windows NT 10.0; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0。
  • REQUEST_FILENAME 當前請求的檔名

RewriteRule 寫法和規則

RewriteRule是配合RewriteCond一起使用,可以說,RewriteRule是RewriteCond成功匹配後的執行結果,所以,它是很重要的。

RewriteRule的格式

RewriteRule Pattern Substitution [flags]

Pattern是一個正則匹配。Substitution是匹配的替換 [flags]是一些引數限制;

舉幾個栗子:

RewriteRule ^room/video/(d+).html web/index.php?c=room&a=video&r=$1 [QSA,NC,L]

意思是以 room開頭的 room/video/123.html 這樣子,變成 web/index.php?c=room&a=video&r=123

RewriteRule .(jpg|gif) http://image.baidu.com/ [R,NC,L]

意思是以為是訪問.jpg或者gif的檔案,都會調整到 http://image.baidu.com

從上面看出,掌握Rewrite,學習正規表示式是關鍵所在。

我們再看看[flags]是什麼意思?

因為它太多了。我就挑幾個最常用的來說說。

  • [QSA] qsappend(追加查詢字串)的意思,次標記強制重寫引擎在已有的替換字串中追加一個查詢字串,而不是簡單的替換。如果需要通過重寫規則在請求串中增加資訊,就可以使用這個標記。上面那個room的例子,就必須用它。
  • [NC] nocase(忽略大小寫)的意思,它使Pattern忽略大小寫,也就是在Pattern與當前URL匹配時,”A-Z”和”a-z”沒有區別。這個一般也會加上,因為我們的url本身就不區分大小寫的。
  • [R] redirect(強制重定向)的意思,適合匹配Pattern後,Substitution是一個http地址url的情況,就定向出去了。上面那個定向到image.baidu.com的例子,就必須也用它。
  • [L] last(結尾規則)的意思,就是已經匹配到了,就立即停止,不再匹配下面的Rule了,類似於程式語言中的break語法,跳出去了。

參考

apache的虛擬域名rewrite配置以及.htaccess的使用。
Apache的Rewrite詳解

相關文章