重寫規則
【重寫規則的作用范圍】
- 可以使用在Apache主配置文件httpd.conf中
- 可以使用在httpd.conf里定義的虛擬主機配置中
- 可以使用在基本目錄的跨越配置文件.htaccess中
【重寫規則的應用條件】
只有當用戶的WEB請求最終被導向到某臺WEB服務器的Apache后臺,則這臺WEB服務器接受進來的請求,根據配置文件該請求是主配置還是虛擬主機,再根據用戶在瀏覽器中請求的URI來配對重寫規則并且根據實際的請求路徑配對.htaccess中的重寫規則。最后把請求的內容傳回給用戶,該響應可能有兩種:
對瀏覽器請求內容的外部重定向(Redirect)到另一個URL。讓瀏覽器再次以新的URI發出請求(R=301或者R=302,臨時的或是永久的重定向)
如:一個網站有正規的URL和別名URL,對別名URL進行重定向到正規URL,或者網站改換成了新的域名則把舊的域名重定向到新的域名(Redirect)也可能是由Apache內部子請求代理產生新的內容送回給客戶[P,L]這是Apache內部根據重寫后的URI內部通過代理模塊請求內容并送回內容給客戶,而客戶端瀏覽器并不知道,瀏覽器中的URI不會被重寫。但實際內容被Apache根據重寫規則后的URI得到。
如:在公司防火墻上運行的Apache啟動這種代理重寫規則,代理對內部網段上的WEB服務器的請求。
【重寫規則怎樣工作?】
我們假定在編譯Apache時已經把mod_rewrite編譯成模塊,確信你的httpd.conf中有LoadModule rewrite_module libexec/mod_rewrite.so并且在Addmodule中有Addmodule mod_rewrite.c則可以使用重寫規則。
當外部請求來到Apache,Apache調用重寫規則中的定義來重寫由用戶瀏覽器指定請求的URI,最后被重寫的URI如果是重定向,則送由瀏覽器作再一次請求;如果是代理則把重寫后的URI交給代理模塊請求最終的內容(Content),最后把內容送回給瀏覽器。
【Apache】
1.檢測Apache是否支持mod_rewrite:LoadModule rewrite_module
2.讓apache服務器支持.htaccess
Options FollowSymLinks
AllowOverride None
改為
Options FollowSymLinks
AllowOverride All
Rewirte主要的功能就是實現URL的跳轉,它的正則表達式是基于Perl語言。可基于服務器級的(httpd.conf)和目錄級的(.htaccess) 兩種方式:
方法有兩種一種是編譯apache的時候就直接安裝rewrite模塊,另一種是編譯apache時以DSO模式安裝apache,然后再利用源碼和apxs來安裝rewrite模塊。
基于服務器級的(httpd.conf)有兩種方法,
一種是在httpd.conf的全局下直接利用RewriteEngine on來打開rewrite功能;
NameVirtualHost 192.168.100.8:80
ServerAdmin webmaster@colorme.com.cn
DocumentRoot "/web/webapp"
ServerName www.colorme.com.cn
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www.colorme.com.cn [NC]
RewriteCond %{HTTP_HOST} !^203.81.23.202 [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/(.*) http://www.colorme.com.cn/ [L]
一種是在局部里利用RewriteEngine on來打開rewrite功能。
下面是一個典型的htaccess文件
開啟URL重寫
RewriteEngine on
URL重寫的作用域
RewriteBase /path/to/url
滿足怎樣的條件
RewriteCond %{HTTP_HOST} !^www.example.com$ [NC]
應用怎樣的規則
RewriteRule .? http://www.example.com%{REQUEST_URI} [R=301,L]
來看看RewriteCond,首先有一個%,因為{HTTP_HOST}是一個apache變量,需要用%來指示。從!開始就是匹配的條件,支持 正則。!表示不等于,這句話的意思就是:如果HTTP_HOST不是www.example.com。后面的[NC](no case)表示忽略大小寫,常見的還有
L:終止一系列的RewriteCond和RewriteRule
R:觸發一個顯示的跳轉,也可以指定跳轉類型,如[R=301]
F:禁止查看特定文件,apache會觸發403錯誤
【Nginx】
見NGINX文檔
【IIS】
下載http://www.helicontech.com/download/isapi_rewrite/ISAPI_Rewrite3_0056_Lite.msi
打開C:\Program Files\Helicon\ISAPI_Rewrite3\httpd.conf
選學
【例子】
圖片防盜鏈
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www.)?example.com/ [NC]
RewriteRule .(gif|jpg|png)$ - [F]
=============================================================
網站升級的時候,只有特定IP才能訪問,其他的用戶將看到一個升級頁面
=============================================================
RewriteEngine on
RewriteCond %{REQUEST_URI} !/upgrade.html$
RewriteCond %{REMOTE_HOST} !^24.121.202.30
RewriteRule $ http://www.nbphp.com/upgrade.html [R=302,L]
===================
把老的域名轉向新域名
===================
redirect from old domain to new domain
RewriteEngine On
RewriteRule ^(.*)$http://www.yourdomain.com/$1[R=301,L]
=================
引出錯誤文檔的目錄
=================
ErrorDocument 400 /errors/badrequest.html
ErrorDocument 404 http://yoursite/errors/notfound.html
ErrorDocument 401 “Authorization Required
常見HTTP狀態碼
Successful Client Requests
200 OK
201 Created
202 Accepted
203 Non-Authorative Information
204 No Content
205 Reset Content
206 Partial Content
Client Request Redirected
300 Multiple Choices
301 Moved Permanently
302 Moved Temporarily
303 See Other
304 Not Modified
305 Use Proxy
Client Request Errors
400 Bad Request
401 Authorization Required
402 Payment Required (not used yet)
403 Forbidden
404 Not Found
405 Method Not Allowed
406 Not Acceptable (encoding)
407 Proxy Authentication Required
408 Request Timed Out
409 Conflicting Request
410 Gone
411 Content Length Required
412 Precondition Failed
413 Request Entity Too Long
414 Request URI Too Long
415 Unsupported Media Type
Server Errors
500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
505 HTTP Version Not Supported
5.2 Blocking users by IP 根據IP阻止用戶訪問
order allow,deny
deny from 123.45.6.7
deny from 12.34.5. (整個C類地址)
allow from all
===========
設置默認首頁
===========
serve alternate default index page
DirectoryIndex about.html
把一些老的鏈接轉到新的鏈接上——搜索引擎優化SEO
Redirect 301 /d/file.htmlhttp://www.htaccesselite.com/r/file.html
為服務器管理員設置電子郵件。
ServerSignature EMail
SetEnv SERVER_ADMINdefault@domain.com
============================
Password Protection 密碼保護
============================
Official document: Authentication, Authorization and Access Control
假設密碼文件為.htpasswd
AuthUserFile /usr/local/safedir/.htpasswd (這里必須使用全路徑名)
AuthName EnterPassword
AuthType Basic
兩種常見驗證方式:
Require user windix
(僅允許用戶windix登陸)
Require valid-user
(所有合法用戶都可登陸)
Tip: 如何生成密碼文件
使用htpasswd命令(apache自帶)
第一次生成需要創建密碼文件
htpasswd -c .htpasswd user1
之后增加新用戶
htpasswd .htpasswd user2
=======================================================================
Enabling SSI Via htaccess 通過htaccess允許SSI(Server Side Including)功能
=======================================================================
AddType text/html .shtml
AddHandler server-parsed .shtml
Options Indexes FollowSymLinks Includes
DirectoryIndex index.shtml index.html
======================================
Blocking users by IP 根據IP阻止用戶訪問
======================================
order allow,deny
deny from 123.45.6.7
deny from 12.34.5. (整個C類地址)
allow from all
==============================================================
Blocking users/sites by referrer 根據referrer阻止用戶/站點訪問
==============================================================
例1. 阻止單一referrer: badsite.com
RewriteEngine on
Options +FollowSymlinks
RewriteCond %{HTTP_REFERER} badsite.com [NC]
RewriteRule .* - [F]
例2. 阻止多個referrer: badsite1.com, badsite2.com
RewriteEngine on
Options +FollowSymlinks
RewriteCond %{HTTP_REFERER} badsite1.com [NC,OR]
RewriteCond %{HTTP_REFERER} badsite2.com
RewriteRule .* - [F]
[NC] - 大小寫不敏感(Case-insensite)
[F] - 403 Forbidden
注意以上代碼注釋掉了”Options +FollowSymlinks”這個語句。如果服務器未在 httpd.conf 的 段落設置 FollowSymLinks, 則需要加上這句,否則會得到”500 Internal Server error”錯誤。
===============================================================================
Blocking bad bots and site rippers (aka offline browsers) 阻止壞爬蟲和離線瀏覽器
===============================================================================
需要mod_rewrite模塊
壞爬蟲? 比如一些抓垃圾email地址的爬蟲和不遵守robots.txt的爬蟲(如baidu?)
可以根據 HTTP_USER_AGENT 來判斷它們
(但是還有更無恥的如”中搜 zhongsou.com”之流把自己的agent設置為 “Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)” 太流氓了,就無能為力了)
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} ^BlackWidow [OR]
RewriteCond %{HTTP_USER_AGENT} ^Bot\ mailto:craftbot@yahoo.com [OR]
RewriteCond %{HTTP_USER_AGENT} ^ChinaClaw [OR]
RewriteCond %{HTTP_USER_AGENT} ^Custo [OR]
RewriteCond %{HTTP_USER_AGENT} ^DISCo [OR]
RewriteCond %{HTTP_USER_AGENT} ^Download\ Demon [OR]
RewriteCond %{HTTP_USER_AGENT} ^eCatch [OR]
RewriteCond %{HTTP_USER_AGENT} ^EirGrabber [OR]
RewriteCond %{HTTP_USER_AGENT} ^EmailSiphon [OR]
RewriteCond %{HTTP_USER_AGENT} ^EmailWolf [OR]
RewriteCond %{HTTP_USER_AGENT} ^Express\ WebPictures [OR]
RewriteCond %{HTTP_USER_AGENT} ^ExtractorPro [OR]
RewriteCond %{HTTP_USER_AGENT} ^EyeNetIE [OR]
RewriteCond %{HTTP_USER_AGENT} ^FlashGet [OR]
RewriteCond %{HTTP_USER_AGENT} ^GetRight [OR]
RewriteCond %{HTTP_USER_AGENT} ^GetWeb! [OR]
RewriteCond %{HTTP_USER_AGENT} ^Go!Zilla [OR]
RewriteCond %{HTTP_USER_AGENT} ^Go-Ahead-Got-It [OR]
RewriteCond %{HTTP_USER_AGENT} ^GrabNet [OR]
RewriteCond %{HTTP_USER_AGENT} ^Grafula [OR]
RewriteCond %{HTTP_USER_AGENT} ^HMView [OR]
RewriteCond %{HTTP_USER_AGENT} HTTrack [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^Image\ Stripper [OR]
RewriteCond %{HTTP_USER_AGENT} ^Image\ Sucker [OR]
RewriteCond %{HTTP_USER_AGENT} Indy\ Library [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^InterGET [OR]
RewriteCond %{HTTP_USER_AGENT} ^Internet\ Ninja [OR]
RewriteCond %{HTTP_USER_AGENT} ^JetCar [OR]
RewriteCond %{HTTP_USER_AGENT} ^JOC\ Web\ Spider [OR]
RewriteCond %{HTTP_USER_AGENT} ^larbin [OR]
RewriteCond %{HTTP_USER_AGENT} ^LeechFTP [OR]
RewriteCond %{HTTP_USER_AGENT} ^Mass\ Downloader [OR]
RewriteCond %{HTTP_USER_AGENT} ^MIDown\ tool [OR]
RewriteCond %{HTTP_USER_AGENT} ^Mister\ PiX [OR]
RewriteCond %{HTTP_USER_AGENT} ^Navroad [OR]
RewriteCond %{HTTP_USER_AGENT} ^NearSite [OR]
RewriteCond %{HTTP_USER_AGENT} ^NetAnts [OR]
RewriteCond %{HTTP_USER_AGENT} ^NetSpider [OR]
RewriteCond %{HTTP_USER_AGENT} ^Net\ Vampire [OR]
RewriteCond %{HTTP_USER_AGENT} ^NetZIP [OR]
RewriteCond %{HTTP_USER_AGENT} ^Octopus [OR]
RewriteCond %{HTTP_USER_AGENT} ^Offline\ Explorer [OR]
RewriteCond %{HTTP_USER_AGENT} ^Offline\ Navigator [OR]
RewriteCond %{HTTP_USER_AGENT} ^PageGrabber [OR]
RewriteCond %{HTTP_USER_AGENT} ^Papa\ Foto [OR]
RewriteCond %{HTTP_USER_AGENT} ^pavuk [OR]
RewriteCond %{HTTP_USER_AGENT} ^pcBrowser [OR]
RewriteCond %{HTTP_USER_AGENT} ^RealDownload [OR]
RewriteCond %{HTTP_USER_AGENT} ^ReGet [OR]
RewriteCond %{HTTP_USER_AGENT} ^SiteSnagger [OR]
RewriteCond %{HTTP_USER_AGENT} ^SmartDownload [OR]
RewriteCond %{HTTP_USER_AGENT} ^SuperBot [OR]
RewriteCond %{HTTP_USER_AGENT} ^SuperHTTP [OR]
RewriteCond %{HTTP_USER_AGENT} ^Surfbot [OR]
RewriteCond %{HTTP_USER_AGENT} ^tAkeOut [OR]
RewriteCond %{HTTP_USER_AGENT} ^Teleport\ Pro [OR]
RewriteCond %{HTTP_USER_AGENT} ^VoidEYE [OR]
RewriteCond %{HTTP_USER_AGENT} ^Web\ Image\ Collector [OR]
RewriteCond %{HTTP_USER_AGENT} ^Web\ Sucker [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebAuto [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebCopier [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebFetch [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebGo\ IS [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebLeacher [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebReaper [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebSauger [OR]
RewriteCond %{HTTP_USER_AGENT} ^Website\ eXtractor [OR]
RewriteCond %{HTTP_USER_AGENT} ^Website\ Quester [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebStripper [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebWhacker [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebZIP [OR]
RewriteCond %{HTTP_USER_AGENT} ^Wget [OR]
RewriteCond %{HTTP_USER_AGENT} ^Widow [OR]
RewriteCond %{HTTP_USER_AGENT} ^WWWOFFLE [OR]
RewriteCond %{HTTP_USER_AGENT} ^Xaldon\ WebSpider [OR]
RewriteCond %{HTTP_USER_AGENT} ^Zeus
RewriteRule ^.* - [F,L]
[F] - 403 Forbidden
[L] - 連接(Link)
==================================================
Change your default directory page 改變缺省目錄頁面
==================================================
DirectoryIndex index.html index.php index.cgi index.pl
==============
Redirects 轉向
==============
單個文件
Redirect /old_dir/old_file.html http://yoursite.com/new_dir/new_file.html
整個目錄
Redirect /old_dir http://yoursite.com/new_dir
效果: 如同將目錄移動位置一樣
http://yoursite.com/old_dir -> http://yoursite.com/new_dir
http://yoursite.com/old_dir/dir1/test.html -> http://yoursite.com/new_dir/dir1/test.html
Tip: 使用用戶目錄時Redirect不能轉向的解決方法
當你使用Apache默認的用戶目錄,如 http://mysite.com/~windix,當你想轉向 http://mysite.com/~windix/jump時,你會發現下面這個Redirect不工作:
Redirect /jump http://www.google.com
正確的方法是改成
Redirect /~windix/jump http://www.google.com
(source: .htaccess Redirect in “Sites” not redirecting: why?
)
========================================================
Prevent viewing of .htaccess file 防止.htaccess文件被查看
========================================================
order allow,deny
deny from all
Adding MIME Types 添加 MIME 類型
AddType application/x-shockwave-flash swf
Tips: 設置類型為 application/octet-stream 將提示下載
===========================================================
Preventing hot linking of images and other file types 防盜鏈
============================================================
需要mod_rewrite模塊
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www/.)?mydomain.com/.*$ [NC]
RewriteRule .(gif|jpg|js|css)$ - [F]
解析:
若 HTTP_REFERER 非空 (來源為其他站點,非直接連接) 并且
若 HTTP_REFERER 非(www.)mydomain.com開頭(忽略大小寫[NC]) (來源非本站)
對于所有含有 .gif/.jpg/.js/.css 結尾的文件給出 403 Forbidden 錯誤[F]
也可指定響應,如下例顯示替換圖片
RewriteRule .(gif|jpg)$ [R,L]
[R] - 轉向(Redirect)
[L] - 連接(Link)
==============================================
Preventing Directory Listing 防止目錄列表時顯示
==============================================
IndexIgnore *
IndexIgnore *.jpg *.gif
Tips:
允許目錄列表顯示: Options +Indexes
禁止目錄列表顯示: Options -Indexes
顯示提示信息: 頁首 文件HEADER, 頁尾 文件README
==================
限制PHP上傳文件大小
==================
這招在共享空間的服務器上很有用,可以讓我的用戶上傳更大的文件。第一個是設置最大的上傳文件大小,第二個是設置最大的POST請求大小,第三個PHP腳本最長的執行時間,最后一個是腳本解析上傳文件的最長時間:
php_value upload_max_filesize 20M
php_value post_max_size 20M
php_value max_execution_time 200
php_value max_input_time 200
【基礎知識】
htaccess基本語法介紹
開啟重寫引擎 :RewriteEngine on
設置重寫的根目錄:RewriteBase / — 說明 :因為定義了這個文件夾,所以對應的替換就有了一個參照。
匹配所有符合條件的請求:RewriteCond — 說明:RewriteCond 定義了一系列規則條件,這個指令可以有一條或者多條,只有用戶拿來的url符合這些條件之后,我們的.htaccess才開始接待,否則用戶就直接自己去訪問所需要的目錄了。
========
常量
========
%{HTTP_HOST}表示當前訪問的網址,只是指前綴部分,格式是www.xxx.com不包括“http://”和“/”
%{REQUEST_URI}表示訪問的相對地址,就是相對根目錄的地址,就是域名/后面的成分,格式上包括最前面的“/”
%{REQUEST_FILENAME}
%{HTTP_REFERER}
==========
正則表達式
==========
[] —— 匹配一個字符集合,例如[xyz]可以匹配x, y或者z
[]+ —— 例如[xyz]+會以任何順序、次數匹配x,y,z的出現
[^] —— 字符表示字符集的補集。[xyz]將匹配沒有x,y或者z的字符串
[a-z] —— 連字符(-)表示匹配從字母a到字母z的所有字符串
a{n} —— 指定字母a出現的次數為n次,滿足該條件時匹配。例如x{3}僅與xxx匹配
a{n,} —— 指定字母a出現的次數至少為n次,例如x{3,}可以與xxx或者xxxx等匹配
a{n,m} —— 指定a出現的次數至少為n到m次。
() —— 用于將正則表達式分組,滿足第一組正則表達式的字符串會被存儲在變量$1中,以此類推。如果括號中的不是正則表達式,例如(perishable)?press 將能夠匹配有或者沒有perishable前綴的press
^ —— 位于行首。注意:和中括號中的[^]意義不同。
$ —— 位于行末
? —— 例如 monzas? 會匹配 monza 或者 monzas,而 mon(za)? 會匹配 mon 或者 monza。又如 x? 會匹配“空字符” 或者 一個x
! —— 邏輯非。例如“!string” 將會匹配除了“string”以外的所有字符串
. —— 表示任意字符串
– —— 命令Apache“不要”重寫URL,例如“xxx.domain.com.* – [F]”
- —— 匹配至少一個任意字符,例如G+匹配以G開頭、并且后面至少有一個字符的字符串
- —— 匹配零個或多個字符,例如“.”匹配任意字符串
| —— 邏輯“或”,與[OR]不同的是,它只匹配字符串,例如(x|y)匹配x或者y
\ —— 轉義字符。可以轉義左括號( 尖字符^ 美元符號$ 感嘆號! 點. 星號 管道符號| 右括號) 等
. —— 轉義為點字符(點字符在正則表達式中可以匹配任意字符)
/* —— 零個或多個正斜杠
.* —— 零個或多個任意字符(即,匹配任意字符串,包括空字符)
^$ —— 匹配“空字符”、“空行”
^.$ —— 匹配任意字符串(僅限一行)
[^/.] —— 匹配既非“正斜杠”也不是“點”的任意字符
[^/.]+ —— 匹配第一個字符既非“正斜杠”也不是“點”,后繼字符可以是“正斜杠”或者“點”的字符串
http:// —— 匹配“http://”
^domain. —— 匹配以“domain”開始的字符串
^domain.com$ —— 僅匹配“domain.com”
\w匹配字母或數字或下劃線或漢字
\s匹配任意的空白符
\d匹配數字
\b匹配單詞的開始或結束
-d —— 測試字符串是否是已存在的目錄
-f —— 測試字符串是否是已存在的文件
-s —— 測試字符串所指文件是否有“非零”值
注意:
RewriteRule ^([0-9]+).html?req_id=(.*)$ p.php?id=$1&req_id=$2
?后面部分是不會進入RewriteRule的,需要用QUERY_STRING變量來獲取
需求1:將http://www.baidu.com/test/one.html?name=miko重寫為http://www.baidu.com/two.html?name=miko,重寫語句如下:
RewriteRule ^test/one.html$ two.html [QSA]
需求2:將http://www.baidu.com/test/one.html?name=miko重寫為http://www.baidu.com/miko.html,重寫語句如下:
RewriteCond %{QUERY_STRING} ^name=(/w+)$
RewriteRule ^test/one.html %1.html
===================================
Apache mod_rewrite規則重寫的標志一覽
===================================
R[=code](force redirect) 強制外部重定向 強制在替代字符串加上http://thishost[:thisport]/前綴重定向到外部的URL.如果code不指定,將用缺省的302 HTTP狀態碼。
F(force URL to be forbidden)禁用URL,返回403HTTP狀態碼。
G(force URL to be gone) 強制URL為GONE,返回410HTTP狀態碼。
P(force proxy) 強制使用代理轉發。
L(last rule) 表明當前規則是最后一條規則,停止分析以后規則的重寫。
N(next round) 重新從第一條規則開始運行重寫過程。
C(chained with next rule) 與下一條規則關聯 如果規則匹配則正常處理,該標志無效,如果不匹配,那么下面所有關聯的規則都跳過。
T=MIME-type(force MIME type) 強制MIME類型
NS (used only if no internal sub-request) 只用于不是內部子請求
NC(no case) 不區分大小寫
QSA(query string append) 追加請求字符串
NE(no URI escaping of output) 不在輸出轉義特殊字符例如:RewriteRule /foo/(.*) /bar?arg=P1%3d$1 [R,NE]將能正確的將/foo/zoo轉換成/bar?arg=P1=zed
PT(pass through to next handler) 傳遞給下一個處理例如:RewriteRule ^/abc(.*) /def$1 [PT] # 將會交給/def規則處理Alias /def /ghi
S=num(skip next rule(s)) 跳過num條規則
E=VAR:VAL(set environment variable) 設置環境變量