1. 程式人生 > >apache rewrite 規則

apache rewrite 規則

它的 程序 忽略 dns ipconfig htaccess load com 訪問

啥是虛擬主機呢?就是說把你自己的本地的開發的機子變成一個虛擬域名,比如:你在開發pptv下面的一個項目 127.0.0.1/pptv_trunk,你想把自己的機器域名變成www.pptv.com。那麽你自己的機器訪問方式就成為了一個虛擬域名。

如何配置呢。一步步來:

1 . 打開apache的配置文件 htppd.cnf。分別打開重寫擴展和虛擬主機擴展:

LoadModule rewrite_module modules/mod_rewrite.so 這句前面的 註釋 # 去掉

Include conf/extra/httpd-vhosts.conf 這句前面的 註釋 # 去掉,關鍵之處

window和linux 差不多稍有不同。文件裏面有幾個例子,我們先搞一個,其實很簡單。

NameVirtualHost *:80

<VirtualHost *:80>

DocumentRoot "D:/wamp/www/pptv_trunk"

ServerName www.pptv.com

<Directory "D:/wamp/www/pptv_trunk>

Options Indexes FollowSymLinks

AllowOverride All

Order allow,deny

Allow from all

</Directory>

</VirtualHost>

好,這樣一個虛擬域名在Apache上就配置好了。

3 . 打開windows/Linux的hosts配置文件,這個文件是系統的dns路由文件:

我們編輯一下,綁定剛才的pptv項目,加上這條:

127.0.0.1 pptv.com www.pptv.com

刷新dns:ipconfig /flushdns

虛擬域名VirtualHost配置詳解

什麽是rewrite? 就是重寫,重寫訪問的url連接,有時候為了訪問的url簡潔點,比如:

www.pptv.com/i/?user_id=123&time=123&from=web

我覺得這個地址太長了不夠簡潔,就可以依靠apache的虛擬域名規則把它寫的簡單一點:

www.pptv.com/i/123/123/web

在學習rewrite之前,我們先詳細看一下一個Virtuhost的詳細配置解讀。

我們還是打開剛的一個虛擬域名,我們對著這個講述,如何配置rewirite

NameVirtualHost *:80

<VirtualHost *:80>

DocumentRoot "D:/wamp/www/testphp/"

ServerName php.iyangyi.com

ServerAlias www.pptv.cn #可省略

ServerAdmin [email protected] #可省略

ErrorLog logs/dev-error.log #可省略

CustomLog logs/dev-access.log common #可省略

ErrorDocument 404 logs/404.html #可省略

<Directory "D:/wamp/www/testphp/">

Options Indexes FollowSymLinks

AllowOverride All

Order Allow,Deny

Allow from all

RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-d

RewriteCond %{REQUEST_FILENAME} !-f

RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]

</Directory>

</VirtualHost>

我們一個一個的說下如何配置。

1 . 首先需要申明虛擬域名包塊,采用xml風格,開始和結束符號對應。*.80表示接受任何ip的80端口,一般是這樣寫,不改。

<VirtualHost *:80>

***

</VirtualHost>

2 . 進去之後,就是申明DocumentRoot 這是表示:項目代碼的路徑。填入我們這個項目的代碼所在的根目錄D:/wamp/www/testphp/就可以了

3 . ServerName 這個是我們的虛擬域名,也是這次修改的關鍵。

4 . ServerAlias 這個是我們的虛擬域名的別名,可以不要,他的出現場景就是我們希望另外一個域名也往這個目錄下調整。比如 www.pptv.cn 我們也希望跳到這裏來,就可以這樣做,但是前提是 www.pptv.cn 也要綁定host 127.0.0.1

5 . ServerAdmin 這裏填 服務器管理員的郵箱,也可以不要,當服務器出現故障後,如果提前有配置郵箱的話,會往這個郵箱發郵件,或者是顯示在網頁的錯誤信息當中。一般我們可以不填。

6 . ErrorLog 這裏填 錯誤日誌顯示路徑,當訪問出現錯誤的時候,就會記錄到這裏,註意:logs/dev-error.log 這個文件路徑是apache的安裝目錄下的logs 目錄 。可以不要。

比如我們訪問 http://php.iyangyi.com/f.html 時候, f.html是不存在的一個文件,那麽這次就會被記錄下來了。

在apache/logs/dev-error.log 中記錄下來了:

[Wed Mar 11 11:14:23 2015] [error] [client 127.0.0.1] File does not exist: D:/wamp/www/testphp/f.html

7 . CustomLog 這裏填訪問日誌,用來記錄每一次的請求訪問,可以不要。註意:logs/dev-access.log 這個文件路徑是apache的安裝目錄下的logs 目錄 。記住:路徑後面加common。

比如我們訪問 http://php.iyangyi.com/f.html 時候

在apache/logs/dev-access.log 中記錄下來了這次的訪問:

127.0.0.1 - - [11/Mar/2015:11:14:23 +0800] "GET /f.html HTTP/1.1" 404 177

8 . ErrorDocument 這裏填 403,404等錯誤信息調整頁面,用來訪問出現404頁面等情況時的錯誤頁面展示,比較有用,也可以不要。註意:/404.html 這個文件路徑是項目的根目錄,不是apache的目錄 。

我這裏放到了D:/wamp/www/testphp/404.html 這裏,所以,我們訪問一個不存在的文件時,就會自動跳轉到這個404.html頁面了。

比如我們訪問 http://php.iyangyi.com/f.html 時候,就會顯示404.html的內容:

所以,我們可以根據業務需要把常用的狀態碼都給用上:

ErrorDocument 403 /403.html

ErrorDocument 404 /404.html

ErrorDocument 405 /405.html

ErrorDocument 500 /500.html

ErrorDocument 503 /503.html

9 . <Directory "D:/wamp/www/testphp/"> ***** </Directory> 這個是最重要的一步了,這裏也是填本項目的路徑,然後所有的rewrite規則都是在裏面完成。所以這個是很重要的。(rewrite 規則是在<directory> 內設置的)

10 . 我們進入到<Directory> 層次中,這裏面很多都是很關鍵的。我們主要看一些常用的,也是很關鍵的。Options Indexes FollowSymLinks 這是來設置 是否來顯示文件根目錄的目錄列表的

設置成:Options Indexes FollowSymLinks 就表示:我訪問php.iyangyi.com,如果文件根目錄裏有 index.html(index.php),瀏覽器就會顯示 index.html的內容,如果沒有 index.html,瀏覽器就會顯示這文件根目錄的目錄列表,目錄列表包括文件根目錄下的文件和子目錄。

到底是優先顯示index.php還是index.html 有apache的配置決定的:

<IfModule dir_module>

DirectoryIndex index.html index.htm index.php index.php3

</IfModule>

哪個在前面,目錄下如果有這個文件,就優先顯示哪個。

如果我不想讓別人訪問我的目錄結構咋搞? ,可以將這個Indexs去掉,或者這樣:-Index 就可以啦。

變成:Options FollowSymLinks 或者 Options -Indexes FollowSymLinks

再次訪問 php.iyangyi.com ,我們把index.php和index.html刪掉了,刷新瀏覽器,就會顯示:

Forbidden

You don‘t have permission to access / on this server.

11 . AllowOverride All 這個是幹嘛的呢?其他教材說的很復雜,我們說簡單點,就是允許根目錄下的.htaccess起rewrite作用,下面會說到的,我們在根目錄下放一個.htaccess文件,也是可以起到url rewrite作用的。

如果想禁止掉這個根目錄下的.htaccess文件,就可以這樣: AllowOverride None 就可以了。

12 . Order Deny,Allow Allow from all這2個一般是組合在一起用。用來設置訪問權限 ,設置哪些ip可以訪問這個域名, 哪些ip禁止訪問。

所以order是設置這2個的組合排序, 不區分大小寫,中間用,分開,中間不能有空格。
Order Deny,Allow :表示設定“先檢查禁止設定,沒有設定禁止的全部允許”

Order Allow,Deny : 表示設定“先檢查允許設定,沒有設定允許的全部禁止”

而且最後的訪問結果有第二參數決定!

Deny from All Deny from 127.0.0.1 禁止訪問的ip, all 表示全部
Allow from All Allow from 127.0.0.1 允許訪問的ip, all 表示全部

我們看幾個他們2個組合的例子。

這個例子:

Order Deny,Allow

Deny from All

表示先檢查允許的, 沒有允許的全部禁止。但是下卻沒有Allow,那麽就表示是無條件禁止了所有的訪問了。

Order Deny,Allow

Deny from all

Allow from 127.0.0.1

上面表示 只允許127.0.0.1訪問

Order Allow,Deny

Allow from all

Deny from 127.0.0.1 192.168.1.51

上面表示禁止127.0.0.1和192.168.1.51訪問,其他都可以!

所以這個的組合就可以達到很多的過濾訪問效果。

RewriteCond 與 RewriteRule 指令格式配置詳解

上面花了大量的時間講述VirtualHost 裏面的一些配置參數的寫法和作用,接下來就是rewrite的重點了,3個核心的東西:RewriteEngine,RewriteCond,RewriteRule

RewriteEngine
這個是rewrite的總開關,用來開啟是否啟動url rewrite,要想打開,像這樣就可以了:

RewriteEngine on

RewriteCond 和 RewriteRule
表示指令定義和匹配一個規則條件,讓RewriteRule來重寫。說的簡單點,RewriteCond就像我們程序中的if語句一樣,表示如果符合某個或某幾個條件則執行RewriteCond下面緊鄰的RewriteRule語句,這就是RewriteCond最原始、基礎的功能。

先看個例子:

RewriteEngine on

RewriteCond %{HTTP_USER_AGENT} ^Mozilla//5/.0.*

RewriteRule index.php index.m.php

上面的匹配規則就是:如果匹配到http請求中HTTP_USER_AGENT 是 Mozilla//5/.0.* 開頭的,也就是用FireFox瀏覽器訪問index.php這個文件的時候,會自動讓你訪問到index.m.php這個文件。

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

RewriteCond一般是這樣使用的

RewriteCond %{XXXXXXX} + 正則匹配條件

那麽RewriteCond可以匹配什麽樣的數據請求呢?
它的使用方式是:RewriteCond %{NAME_OF_VARIABLE} REGX FLAG

RewriteCond %{HTTP_REFERER} (www.test.cn)

RewriteCond %{HTTP_USER_AGENT} ^Mozilla//5/.0.*

RewriteCond %{REQUEST_FILENAME} !-f

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

HTTP_REFERER
這個匹配訪問者的地址,php中$_REQUREST中也有這個,當我們需要判斷或者限制訪問的來源的時候,就可以用它。

比如:

RewriteCond %{HTTP_REFERER} (www.test.cn)

RewriteRule (.*)$ test.php

上面語句的作用是如果你訪問的上一個頁面的主機地址是www.test.cn,則無論你當前訪問的是哪個頁面,都會跳轉到對test.php的訪問。

再比如,也可以利用 HTTP_REFERER 防倒鏈,就是限制別人網站使用我網站的圖片。

RewriteCond %{HTTP_REFERER} !^$ [NC]

RewriteCond %{HTTP_REFERER} !ww.iyangyi.com [NC]

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

NC nocase的意思,忽略大小寫。第一句呢,是必須要有域名,第一句就是看域名如果不是 www.iyangyi.com 的,當訪問.jpg或者.gif文件時候,就都會自動跳轉到 http://image.baidu.com/ 上,很好的達到了防盜鏈的要求。

REQUEST_FILENAME
這個基本是用的最多的,以為url重寫是用的最多的,它是匹配當前訪問的域名文件,那哪一塊屬於REQUEST_FILENAME 呢?是url 除了host域名外的。

http://www.rainleaves.com/html/1569.html?replytocom=265

這個url,那麽 REQUEST_FILENAME 就是 html/1569.html?replytocom=265

看個例子:

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

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

-d 是否是一個目錄. 判斷TestString是否不是一個目錄可以這樣: !-d
-f 是否是一個文件. 判斷TestString是否不是一個文件可以這樣: !-f

這兩句語句RewriteCond的意思是請求的文件或路徑是不存在的,如果文件或路徑存在將返回已經存在的文件或路徑。一般是這樣結合在一起用的。

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

$1 表示匹配到的第一個參數

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

所以,掌握正則級是關鍵所在了。以後,我會專門搞一個正則的篇章來學習下。

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

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

[QSA] qsappend(追加查詢字符串)的意思,次標記強制重寫引擎在已有的替換字符串中追加一個查詢字符串,而不是簡單的替換。如果需要通過重寫規則在請求串中增加信息,就可以使用這個標記。上面那個room的例子,就必須用它。

NC nocase(忽略大小寫)的意思,它使Pattern忽略大小寫,也就是在Pattern與當前URL匹配時,"A-Z"和"a-z"沒有區別。這個一般也會加上,因為我們的url本身就不區分大小寫的。

R redirect(強制重定向)的意思,適合匹配Patter後,Substitution是一個http地址url的情況,就調整出去了。上面那個調整到image.baidu.com的例子,就必須也用它。

L last(結尾規則)的意思,就是已經匹配到了,就立即停止,不再匹配下面的Rule了,類似於編程語言中的break語法,跳出去了。

其他的一些具體的語法,可以參考以下資料

apache rewrite 規則