偽靜態的產生主要是為了增強搜索引擎的友好度,方便用戶記憶。一般通過正則匹配來重寫動態網站的URL使其靜態化。那么在Windows平台下如何設置Apache支持URL重寫功能,以及如何配置.htaccess文件來實現偽靜態呢?
一、讓Apache支持URL重寫
在httpd.conf中加載mod_rewrite.so組件開啟Apache中的URL重寫功能。
二、配置.htaccess文件,定義重寫規則
1、 在配置重寫規則之前,需要在httpd.conf中設置AllowOverride All(至少設置為AllowOverride FileInfo)讓Apache能夠正常的讀取.htaccess 文件的內容。
偽靜態的產生主要是為了增強搜索引擎的友好度,方便用戶記憶。一般通過正則匹配來重寫動態網站的URL使其靜態化。那么在Windows平台下如何設置Apache支持URL重寫功能,以及如何配置.htaccess文件來實現偽靜態呢?
一、讓Apache支持URL重寫
在httpd.conf中加載mod_rewrite.so組件開啟Apache中的URL重寫功能。
二、配置.htaccess文件,定義重寫規則
1、 在配置重寫規則之前,需要在httpd.conf中設置AllowOverride All(至少設置為AllowOverride FileInfo)讓Apache能夠正常的讀取.htaccess 文件的內容。
<Directory />
Options FollowSymLinks
AllowOverride FileInfo
</Directory>
- 1
- 2
- 3
- 4
2、在.htaccess中定義重寫規則。
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([A-Za-z_]+)$ index.php?m=$1
- 1
- 2
- 3
- 4
RewriteEngine on打開rewrite功能
RewriteCond指令格式
- 語法: RewriteCond TestString CondPattern [flags]
- 生效域: server config, virtual host, directory, .htaccess
- RewriteCond指令定義一條規則條件。在一條RewriteRule指令前面可能會有一條或多條RewriteCond指令,只有當自身的模板(pattern)匹配成功且這些條件也滿足時規則才被應用於當前URL處理。
- TestString是一個純文本的字符串,除了包含普通的字符外,還可以包括下列的可擴展結構:
- $N:RewriteRule后向引用,其中(0 <= N <= 9) 。$N引用緊跟在RewriteCond后面的RewriteRule中模板中的括號中的模板在當前URL中匹配的數據。
- %N:RewriteCond后向引用,其中(0 <= N <= 9) 。%N引用最后一個RewriteCond的模板中的括號中的模板在當前URL中匹配的數據。
- ${mapname:key|default}:RewriteMap擴展。
-
CondPattern是條件pattern,即一個應用於當前實例TestString的正則表達式,即TestString將會被計算然后與CondPattern匹配。作為一個標准的擴展正則式,CondPattern有以下補充:
- 可以在模板串前增加一個!前綴,以用表示不匹配模板。但並不是所有的test都可以加!前綴。
- CondPattern中可以使用以下特殊變量:
- >CondPattern(大於) 將condPattern當作一個普通字符串,將它和TestString進行比較,當TestString 的字符大於CondPattern為真。
- =CondPattern(等於) 將condPattern當作一個普通字符串,將它和TestString進行比較,當TestString 與CondPattern完全相同時為真.如果CondPattern只是”“(兩個引號緊挨在一起) 此時需TestString 為空字符串方為真。
- -d(是否為目錄) 將testString當作一個目錄名,檢查它是否存在以及是否是一個目錄。
- -f (是否是regular file) 將testString當作一個文件名,檢查它是否存在以及是否是一個regular文件。
- -s (是否為長度不為0的regular文件) 將testString當作一個文件名,檢查它是否存在以及是否是一個長度大於0的regular文件。
- -l (是否為symbolic link) 將testString當作一個文件名,檢查它是否存在以及是否是一個 symbolic link。
- -F(通過subrequest來檢查某文件是否可訪問) 檢查TestString是否是一個合法的文件,而且通過服務器范圍內的當前設置的訪問控制進行訪問。這個檢查是通過一個內部subrequest完成的, 因此需要小心使用這個功能以降低服務器的性能。
- -U (通過subrequest來檢查某個URL是否存在) 檢查TestString是否是一個合法的URL,而且通過服務器范圍內的當前設置的訪問控制進行訪問。這個檢查是通過一個內部subrequest完成的, 因此需要小心使用這個功能以降低服務器的性能。
-
[flags]是第三個參數,多個標志之間用逗號分隔。
- nocase|NC (不區分大小寫) 在擴展后的TestString和CondPattern中,比較時不區分文本的大小寫。注意,這個標志對文件系統和subrequest檢查沒有影響。
-
ornext|OR(建立與下一個條件的或的關系) 默認的情況下,二個條件之間是AND的關系,用這個標志將關系改為OR。例如:
RewriteCond %{REMOTE_HOST} ^host1.* [OR] RewriteCond %{REMOTE_HOST} ^host2.* [OR] RewriteCond %{REMOTE_HOST} ^host3.* RewriteRule …- 1
- 2
- 3
- 4
如果沒有[OR]標志,需要寫三個條件/規則。
RewriteRule 指令
- 語法: RewriteRule Pattern Substitution [flags]
- Pattern是一個作用於當前URL的兼容perl的正則表達式. 這里的“當前”是指該規則生效時的URL的值。
- Substitution是,當原始URL與Pattern相匹配時,用以替代(或替換)的字符串此外,Substitution還可以追加特殊標記[flags] 作為RewriteRule指令的第三個參數。
-
Flags是一個包含以逗號分隔的下列標記
- forbidden|F (強制URL為被禁止的 forbidden) 強制當前URL為被禁止的,即,立即反饋一個HTTP響應代碼403(被禁止的)。使用這個標記,可以鏈接若干RewriteConds以有條件地阻塞某些URL。
- gone|G(強制URL為已廢棄的 gone) 強制當前URL為已廢棄的,即,立即反饋一個HTTP響應代碼410(已廢棄的)。使用這個標記,可以標明頁面已經被廢棄而不存在了.
- proxy|P (強制為代理 proxy) 此標記使替換成分被內部地強制為代理請求,並立即(重寫規則處理立即中斷)把處理移交給代理模塊。你必須確保此替換串是一個有效的(比如常見的以 http://hostname開頭的)能夠為Apache代理模塊所處理的URI。使用這個標記,可以把某些遠程成分映射到本地服務器名稱空間,從而增強了ProxyPass指令的功能。(注意: 要使用這個功能,代理模塊必須編譯在Apache服務器中。如果你不能確定,可以檢查“httpd -l”的輸出中是否有mod_proxy.c。如果有,則mod_rewrite可以使用這個功能;如果沒有,則必須啟用mod_proxy並重新編譯“httpd”程序。)
-
last|L (最后一個規則 last) 立即停止重寫操作,並不再應用其他重寫規則。它對應於Perl中的last命令或C語言中的break命令。這個標記可以阻止當前已被重寫的URL為其后繼的規則所重寫。例如,使用它可以重寫根路徑的URL(’/’)為實際存在的URL, 比如, ‘/e/www/’。
-
next|N (重新執行 next round) 重新執行重寫操作(從第一個規則重新開始). 這時再次進行處理的URL已經不是原始的URL了,而是經最后一個重寫規則處理的URL。它對應於Perl中的next命令或C語言中的continue命令。 此標記可以重新開始重寫操作,即, 立即回到循環的頭部。但是要小心,不要制造死循環!
- chain|C (與下一個規則相鏈接 chained) 此標記使當前規則與下一個(其本身又可以與其后繼規則相鏈接的, 並可以如此反復的)規則相鏈接。 它產生這樣一個效果: 如果一個規則被匹配,通常會繼續處理其后繼規則, 即,這個標記不起作用;如果規則不能被匹配,則其后繼的鏈接的規則會被忽略。比如,在執行一個外部重定向時, 對一個目錄級規則集,你可能需要刪除“.www” (此處不應該出現“.www”的)。
- type|T=MIME-type(強制MIME類型type) 強制目標文件的MIME類型為MIME-type 比如,它可以用於模擬mod_alias中的ScriptAlias指令,以內部地強制被映射目錄中的所有文件的MIME類型為“application/x-httpd-cgi”。
- nosubreq|NS (僅用於不對內部子請求進行處理 no internal sub-request) 在當前請求是一個內部子請求時,此標記強制重寫引擎跳過該重寫規則。比如,在mod_include試圖搜索可能的目錄默認文件(index.xxx)時, Apache會內部地產生子請求。對子請求,它不一定有用的,而且如果整個規則集都起作用,它甚至可能會引發錯誤。所以,可以用這個標記來排除某些規則。根據你的需要遵循以下原則: 如果你使用了有CGI腳本的URL前綴,以強制它們由CGI腳本處理,而對子請求處理的出錯率(或者開銷)很高,在這種情況下,可以使用這個標記。
- nocase|NC (忽略大小寫 no case) 它使Pattern忽略大小寫,即, 在Pattern與當前URL匹配時,’A-Z’ 和’a-z’沒有區別。
- qsappend|QSA (追加請求串 query string append) 此標記強制重寫引擎在已有的替換串中追加一個請求串,而不是簡單的替換。如果需要通過重寫規則在請求串中增加信息,就可以使用這個標記。
- noescape|NE (在輸出中不對URI作轉義 no URI escaping) 此標記阻止mod_rewrite對重寫結果應用常規的URI轉義規則。 一般情況下,特殊字符(如’%’, ‘$’, ‘;’等)會被轉義為等值的十六進制編碼。 此標記可以阻止這樣的轉義,以允許百分號等符號出現在輸出中,如:
RewriteRule /foo/(.*) /bar?arg=P1\=$1 [R,NE] 可以使’/foo/zed’轉向到一個安全的請求’/bar?arg=P1=zed’ -
passthrough|PT (移交給下一個處理器 pass through) 此標記強制重寫引擎將內部結構request_rec中的uri字段設置為 filename字段的值,它只是一個小修改,使之能對來自其他URI到文件名翻譯器的 Alias,ScriptAlias, Redirect 等指令的輸出進行后續處理。舉一個能說明其含義的例子:如果要通過mod_rewrite的重寫引擎重寫/abc為/def,然后通過mod_alias使/def轉變為/ghi,可以這樣:
RewriteRule ^/abc(.*) /def$1 [PT] Alias /def /ghi- 1
- 2
如果省略了PT標記,雖然mod_rewrite運作正常,即作為一個使用API的URI到文件名翻譯器,它可以重寫uri=/abc/…為filename=/def/…,但是,后續的mod_alias在試圖作URI到文件名的翻譯時,則會失效。
-
skip|S=num (跳過后繼的規則 skip) 此標記強制重寫引擎跳過當前匹配規則后繼的num個規則。 它可以實現一個偽if-then-else的構造: 最后一個規則是then從句,而被跳過的skip=N個規則是else從句. (它和’chain|C’標記是不同的!)
- env|E=VAR:VAL (設置環境變量 environment variable) 此標記使環境變量VAR的值為VAL, VAL可以包含可擴展的反向引用的正則表達式$N和%N。此標記可以多次使用以設置多個變量。這些變量可以在其后許多情況下被間接引用,但通常是在XSSI (via ) or CGI (如 $ENV{’VAR’})中, 也可以在后繼的RewriteCond指令的pattern中通過%{ENV:VAR}作引用。使用它可以從URL中剝離並記住一些信息。
- cookie|CO=NAME:VAL:domain[:lifetime[:path]] (設置cookie)它在客戶端瀏覽器上設置一個cookie。cookie的名稱是NAME,其值是VAL。domain字段是該cookie的域,比如’.apache.org’, 可選的lifetime是cookie生命期的分鍾數,可選的path是cookie的路徑。
此外,rewrite規則中如果遇到中文,相當有可能會出現亂碼問題,因為apache在rewrite時會做一次url解碼,這時jk進行請求轉發時,就不會再是編碼后的字符串了。此種情況,可以在一開始就進行兩次編碼(encode),或者在接收請求時先用ISO-8859-1取字節流,再使用UFT-8來new String。
三、解決網站不在根目錄Apache解析路徑出錯的問題
若果網站程序不在根目錄,那么偽靜態的URL就容易出錯,解決方法是配置虛擬主機。
1、在httpd.conf中加載httpd-vhosts.conf文件
#Virtual hosts
Include conf/extra/httpd-vhosts.conf
- 1
- 2
2、在httpd-vhosts.conf文件中配置虛擬主機
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host.example.com
DocumentRoot /www/docs/dummy-host.example.com #項目路徑
ServerName dummy-host.example.com #ServerName
ErrorLog logs/dummy-host.example.com-error_log
CustomLog logs/dummy-host.example.com-access_log common
</VirtualHost>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
3、在hosts中加載serverName
總之,要通過Apache服務器實現偽靜態,首先要在httpd.conf中加載mod_rewrite.so模塊,然后配置RewriteRule。當然,在定義RewriteRule之前弄明白網站動態的URL有哪幾類,要匹配的靜態URL的類型,才能更好更快的寫出適合自己網站的RewriteRule。
