apache .htaccess 偽靜態重定向,防盜鏈 限制下載...


301全站跳轉

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.old\.net$ [NC]
RewriteRule ^(.*)$ http://www.new\.net/$1 [L,R=301,NC]

其中 http://不能省略,不然出現絕對路徑加在跳轉重寫前面的

.htaccess 正則表達式
# 位行首表示注釋
[F] Forbidden (禁止):
    命令服務器返回403 Forbiden 錯誤給用戶瀏覽器

[L] Last rule (最后一條規則)
    告訴服務器在本條規則執行完后停止重寫URL

[N] Next (下一條規則)
    告訴服務器繼續重寫,指導所有重寫指令都執行過

[G] Gone (丟失)
    命令服務器返回410 GONE(no longer exists)錯誤消息

[P] Proxy (代理)
    告訴服務器通過mod_proxy模塊處理用戶請求

[C] Chain (捆綁)
    告訴服務器將當前的規則和前面的規則進行捆綁

[R] Redirect(重定向)
    告訴服務器發出重定向消息,以便用戶瀏覽器發出rewitten/modified(重寫/修改) 請求

[NC] No Case(不區分大小寫)
    對客戶端請求的URL不區分大小寫

[PT] Pass Through(放行)
    讓mod_rewrite 模塊將重寫的URL傳回給Apache做進一步處理

[OR] Or(邏輯或)
    用邏輯“或”將兩個表達式連接在一起,如果結果為“真”,則會應用后繼的相關規定

[NE] No Escape (禁止轉義)
    命令服務器在輸出時禁用轉義字符

[NS] No Subrequest(禁用子請求)
    如果存在內部請求,則跳過當前命令

[QSA] Append Query String(追加查詢字符串)
    命令服務器在URL末尾追加查詢字符串

[S=x] Skip(跳過)
    如果滿足某指定條件,則跳過后面第X條規則

[E = Variable:value](環境變量)
    命令服務器交將值 value賦給變量 variable

[T=MIME-type] Mime Type (MIME 類型)
    聲明目標資源所屬的MIME類型

[]
  匹配一個字符集,如[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或者xxxxx等級匹配

a{n,m}
    指定a出現的次數至少為n到m次    

()
  用於將正則表達式分組,滿足第一組正則表達式的字符串會被存儲在變量$1中,以此類推。如果括號呈的不是正則表達式,例如(myname)?press 將能夠匹配有或者沒有myname前綴的press

^
 位於行首。注意:和中括號中的[^]意義不同

$
 位於行末

?
  例如 world?會匹配world或者worldx,而如 wor(ld)? 會匹配wor或者world,又如:x?會匹配“空字符”或者一個x

!
  邏輯非。例如:"!myname"將會匹配除了“myname”以外的所有字符串

.
 表示任意字符

-
 命令apache“不要”重寫URL,例如:"xxx.domian.com.* -[F]"

+
 匹配至少一個任意字符,例如:G+ 匹配以G開頭,並且后面至少有一個字符的字符串

*
 匹配零個或多個字符,例如:“。”匹配任意字符

|
  邏輯“或”。與[OR]不同的是,它是匹配字符串,例如(x|y)匹配x或者y


\
  轉義字符。可以轉義左括號(,尖括號^,美元符號 $, 感嘆號 !點 。 星號 *,管道符號|等,

\.
 轉義為點字符(點字符在正則表達式中可以匹配任意字符)

/*
  零個或多個字符

.*
  零個或多個任意字符(即匹配任意字符,包括空字符)

^$
  匹配“空字符”,“空行”

^.*$
    匹配任意字符串(僅限一行)

[^/.]
    匹配既非“正斜杠”也不是“點”的任意字符

[^/.]+
    匹配第一個字符既非“正斜杠”也不是“點”,后繼字符可以是“正斜杠”或者“點”字符串

http ://
    匹配 http ://

^domain.*
    匹配以"domain"開始的字符串

^domain\.com$
    僅匹配 "domain.com"

-d
    測試字符串是否已存在的目錄  

-f
    測試字符串是否是已經存在的文件

-s
    測試字符串所指文件是否有“非零”值

以下為相關例子:
1。將.htm 頁面映射到 .php

Options +FollowSymlinks
RewriteEngine On
RewriteRule ^(.*)\.htm$ $1.php [NC]

2。臨時重定向(R=302)與永久重定向(R=301)

RewriteEngine On
RewriteBase /
RewriteRule ^(.*)\.htm$ $.php [R,NC,L]
•該RewriteRule能夠將.htm靜態頁面重定向到.php動態頁面
•如果通過.htm進入,瀏覽器地址欄會自動轉為.php,這也是重定向的本質
•必須保證服務器上有對應的.php,否則會404
•瀏覽器和搜索引擎可以同時通過.htm和.php訪問網頁
•如果該目錄上存在.htm,將被忽略
•RewriteBase定義了重寫基准目錄。
•例如,如果你將虛擬站點設置在/var/www目錄下,刪除這行將會導致重定向到h ttp://yourdomain.com/var/www/1.php 。顯然這是找不到的,而且你也不會希望用戶看見你的服務器的目錄結構。
•再舉個例子,如果RewriteBase /base/,那么將會重定向到h ttp://yourdomain.com/base/1.php 。
•對於重寫基准目錄,我們還可以通過將$1.php變成/$1.php實現直接變換,這時就可以將RewriteBase省略。
•字母R表示臨時重定向,相當於[R=302,NC]。關於重定向代碼,請參考h ttp://lesca.me/archives/htaccess-appendix.html 《HTTP協議重定向編碼》
•字母L表示如果能匹配本條規則,那么本條規則是最后一條(Last),忽略之后的規則。

永久得定向 R=301

RewriteEngine On
RewriteRule ^(.*)$ h ttp://newdomain.com/$ [R=301,NC,L]
•這個規則告訴瀏覽器和搜索引擎,網站地址發生了永久性變更,用戶的URL請求將會被發送給新的域名(主機)處理。
•由於是重定向到新的主機地址,RewriteBase也就沒有出現的必要了。

3.為什么要用重定向?——重定向和URL重寫的區別
•通過重定向,瀏覽器知道頁面位置發生變化,從而改變地址欄顯示的地址
•通過重定向,搜索引擎意識到頁面被移動了,從而更新搜索引擎索引,將原來失效的鏈接從搜索結果中移除
•臨時重定向(R=302)和永久重定向(R=301)都是親搜索引擎的,是SEO的重要技術
•URL重寫用於將頁面映射到本站另一頁面,若重寫到另一網絡主機(域名),則按重定向處理

長短地址轉換
利用URL重寫,我們可以很方便地實現長短地址的轉換,但是用重定向就不合適了。

RewriteEngine On
RewriteRule ^grab /public/file/download/download.php

若訪問
h ttp://mysite/grab?file=my.zip

則會執行該頁面:
h ttp://mysite/public/files/download/download.php?file=my.zip

去掉www

options +FollowSymlinks
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
RewriteRule ^(.*)$ h ttp://$1/$1 [R=301,NC,L]

加上www

optionEngine On
RewriteCond %{HTTP_HOST} ^(.*)$
RewriteRule (.*) h ttp://www\.%1/$1 [R=301,L]

支持多域名訪問
如果你不湊巧買到了不支持多域名的主機,那么.htaccess或許可以幫助你。現在假設你有域名domain-one.com和domain-two.com,並且在服務器根目錄有對應文件夾one和two,那么通過下面的改寫就能讓Apache同時接受者兩個域名的請求:

RewriteCond %{HTTP_HOST} domain-one.com
RewriteCond %{REQUEST_URI} !^/one
RewriteRule ^(.*)$ /one/$1 [L]

RewriteCond %{HTTP_HOST} domain-two.com
RewriteCond %{REQUEST_URL} !^/two
RewriteRule ^(.*)$ /two/$1 [L]

改寫查詢字符串QUERY_STRING
查詢字符串是指URL請求中“問號”后面的部分。比如,h ttp://mysite/grab?foo=bar ?部分就是查詢字符串,其中變量名是foo,值是bar。
1.利用QSA轉換查詢字符串QUERY_STRING
QSA標志( Query String Appending)用於在URI中截取查詢字符串,這個截取操作是通過小括號正則表達式實現的:

RewriteEngine On
RewriteRule /pages/(.+) /page.php?page=$1 [QSA]

•將會把請求/pages/123?one=two 映射到 /page.php?page=123&one=two
•注意幾乎是相同的,除了“問號”變成了“與”符號
•如果沒有QSA標志,那么會映射到/page.php?page=123。
•如果沒有用到小括號正則表達式,就不需要QSA
•小括號正則表達式可以截取查詢字符串中的內容,但是如果沒有開啟QSA標志,那么在/page.php?page=$1中“問號”之后將會被剝離丟棄。這種特性可以用於實現“剝離查詢字符串”

通過QSA,我們可以將簡單鏈接/simple/flat/link/ 映射成 server-side.php?first-var=flat&second-var=link

RewriteEngine On
RewriteRule ^/([^/]+)/([^/]+)/? /index.php?first-var=$1&second-var=$2 [QSA]

利用RewriteCond改寫查詢字符串QUERY_STRING
RewriteEngine On
RewriteCond %{QUERY_STRING} foo=(.*)
RewriteRule ^grab(.*) /page.php?bar=%1

該規則將訪問請求htt p://mysite/grab?foo=bar轉換為htt p://mysite/page.php?bar=bar
RewriteCond用於捕獲查詢字符串(QUERY_STRING)中變量foo的值,並存儲在%1中
QUERY_STRING是Apache定義的“變量=值”向量(數組)

QSA與RewriteCond一起用

RewriteEngine On
RewriteCond %{QUERY_STRING} foo=(.+)
RewriteRule ^grab/(.*) /%1/index.php?file=$1 [QSA]

•會把/grab/foobar.zip?level=5&foo=bar 映射到 /bar/index.php?file=foobar.zip&level=5&foo=bar
•轉換后根目錄是bar目錄
•foobar.zip?level=5中的“問號”變成了foobar.zip&level=5中的“與”符號

剝離查詢字符串

只需在要開始剝離的鏈接后面加個“問號”,並且不要啟用QSA標志,就可剝離查詢字符串

RewriteEngine On
RewriteCond %{QUERY_STRING} .
RewriteRule foo.php(.*) /foo.php? [L]

用.htaccess阻止User-agent
什么是User-agent?User-agent用於瀏覽器向服務器“自報家門”,更確切的說是所有HTTP客戶端都得用User-agent向服務器“自報家門”,以便服務器對不同的客戶端作出不同響應。比如,某站點可能需要對瀏覽器、搜索引擎crawl還有各類下載工具作出不同的響應。服務器就是通過所謂的User-agent進行區分的。
如果你的服務器提供某些資源的下載,那么你就必須多加小心諸如“迅雷”等下載軟件,因為它們可能把你網站資源吸干,並且影響你的正常訪客訪問。為此,我們可以利用Rewrite限制某些UA的訪問:


RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} 2.0.50727 [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^BlackWido [NC,OR]
# ect...
RewriteRule . abuse.txt


•該規則限制“迅雷”客戶端下載資源,並將下載文件重置到abuse.txt
•HTTP_USER_AGENT是Apache的內置變量
•2.0.50727是迅雷User-agent的特征字符串
•RewriteRule后面的“點”表示“任意URI”,也就是不管請求的是什么,都輸出abuse.txt

文件訪問控制

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !^(.+)\.css$
RewriteCond %{REQUEST_FILENAME} !^(.+)\.js$
RewriteCond %{REQUEST_FILENAME} !special.zip$
RewriteRule ^(.+)$ /chat/ [NC]

•該規則將僅允許用戶請求.css, .js類型的文件,還有special.zip文件
•RewriteRule 后面指定了限制規則:映射到/char/目錄下處理
•RewriteCond 后面的“感嘆號”(!)起到了“否定”作用,它表明,對不滿足后面正則表達式者應用RewriteRule規則,也就是對當前類型的文件將不應用規則
•RewriteCond 之間是以邏輯“與”連接的,也就是只有當三個條件都不滿足時才執行RewriteRule
•該規則也會限制訪問.htm, .jpg等格式
•該規則不可以放在虛擬站點根目錄(/)下,否則會死循環
•如果是二級目錄,如/test/,那么傳入RewriteCond的參數是以/test/開始的,因此從(.+)獲得的文件名也含有/test/,讀者必須對此多加小心
•要想僅獲得文件名,可以將(.+)替換成([^/]+),並且去掉符號^,如下所示:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !([^/]+)\.css$
RewriteCond %{REQUEST_FILENAME} !([^/]+)\.js$
RewriteRule ^(.+)$ /chat/ [NC]




RewriteEngine Off
#RewiteBase /
RewriteCond %{HTTP_HOST} ^(www\.)?xxx\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/blog/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ blog/$1

# 沒有輸入文件名的默認到到首頁
RewriteCond %{HTTP_HOST} ^(www\.)?xxx\.com$ [NC]
RewriteRule ^(/)?$ blog/index.php [L]

防盜鏈:
RewriteEngine on
#RewiteBase /
RewriteCond %{HTTP_REFERER} !^$ [NC]
RewriteCond %{HTTP_REFERER} !xxx.info [NC]
RewriteCond %{HTTP_REFERER} !(www\.)?baidu.com$ [NC]
RewriteCond %{HTTP_REFERER} !(www\.).google.com$ [NC]
RewriteRule \.(jpg|gif|png|bmp|swf|jpeg)$ /error/daolian.gif [R,NC,L]

【RewriteCond語法】
RewriteCond TestString CondPattern [flags]

rewritecond的其他用法:
"-d"(目錄)
將TestString視為一個路徑名並測試它是否為一個存在的目錄。
"-f"(常規文件)
將TestString視為一個路徑名並測試它是否為一個存在的常規文件。
"-s"(非空的常規文件)
將TestString視為一個路徑名並測試它是否為一個存在的、尺寸大於0的常規文件。
"-l"(符號連接)
將TestString視為一個路徑名並測試它是否為一個存在的符號連接。
"-x"(可執行)
將TestString視為一個路徑名並測試它是否為一個存在的、具有可執行權限的文件。該權限由操作系統檢測。
"-F"(對子請求存在的文件)
檢查TestString是否為一個有效的文件,而且可以在服務器當前的訪問控制配置下被訪問。它使用一個內部子請求來做檢查,由於會降低服務器的性能,所以請謹慎使用!
"-U"(對子請求存在的URL)
檢查TestString是否為一個有效的URL,而且可以在服務器當前的訪問控制配置下被訪問。它使用一個內部子請求來做檢查,由於會降低服務器的性能,所以請謹慎使用!

【RewriteRule語法:】
RewriteRule Pattern Substitution [flags]

【flags】
"chain|C"(鏈接下一規則)


"cookie|CO=NAME:VAL:domain[:lifetime[:path]]"(設置cookie)


"env|E=VAR:VAL"(設置環境變量)


"forbidden|F"(強制禁止URL)


"gone|G"(強制廢棄URL)


"handler|H=Content-handler"(強制指定內容處理器)


"last|L"(結尾規則)


"next|N"(從頭再來)


"nocase|NC"(忽略大小寫)


"noescape|NE"(在輸出中不對URI進行轉義)


"nosubreq|NS"(不對內部子請求進行處理)


"proxy|P"(強制為代理)


"passthrough|PT"(移交給下一個處理器)


"qsappend|QSA"(追加查詢字符串)


"redirect|R [=code]"(強制重定向)


"skip|S=num"(跳過后繼規則)


"type|T=MIME-type"(強制MIME類型)

RewriteRule ^(.+\.php)s$ $1 [T=application/x-httpd-php-source]

示例:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?xxx\.com$ RewriteCond %{REQUEST_URI} !^/blog/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /blog/$1 # 沒有輸入文件名的默認到到首頁 RewriteCond %{HTTP_HOST} ^(www\.)?xxx\.com$ RewriteRule ^(/)?$ blog/index.php [L]

RewriteEngine On】
表示重寫引擎開,關閉off,作用就是方便的開啟或關閉以下的語句,這樣就不需要一條一條的注釋語句了。

RewriteCond %{HTTP_HOST} ^(www\.)?xxx\.com$】
這是重寫條件,前面%{HTTP_HOST}表示當前訪問的網址,只是指前綴部分,格式是www.xxx.com不包括“http://”和“/”,^表示 字符串開始,$表示字符串結尾,\.表示轉義的. ,如果不轉義也行,推薦轉義,防止有些服務器不支持,?表示前面括號www\.出現0次或1次,這句規則的意思就是如果訪問的網址是xxx.com或者 www.xxx.com就執行以下的語句,不符合就跳過。

【RewriteCond %{REQUEST_URI} !^/blog/】
也是重寫條件,%{REQUEST_URI}表示訪問的相對地址,就是相對根目錄的地址,就是域名/后面的成分,格式上包括最前面的“/”,!表示非,這句語句表示訪問的地址不以/blog/開頭,只是開頭^,沒有結尾$

【RewriteCond %{REQUEST_FILENAME} !-f】
【RewriteCond %{REQUEST_FILENAME} !-d】
這兩句語句的意思是請求的文件或路徑是不存在的,如果文件或路徑存在將返回已經存在的文件或路徑

RewriteRule ^(.*)$ /blog/$1】
重寫規則,最重要的部分,意思是當上面的RewriteCond條件都滿足的時候,將會執行此重寫規則,^(.*)$是一個正則表達的 匹配,匹配的是當前請求的URL,^(.*)$意思是匹配當前URL任意字符,.表示任意單個字符,*表示匹配0次或N次(N>0),后面 /blog/$1是重寫成分,意思是將前面匹配的字符重寫成/blog/$1,這個$1表示反向匹配,引用的是前面第一個圓括號的成分,即^(.*)$中 的.* ,其實這兒將會出現一個問題,后面討論。

 

【RewriteCond %{HTTP_HOST} ^(www\.)?xxx\.com$】
【RewriteRule ^(/)?$ blog/index.php [L]】
這兩句的意思是指請求的host地址是www.xxx.com是,如果地址的結尾只有0個或者1個“/”時,將會重寫到子目錄下的主頁,我猜想這主要因為重寫后的地址是不能自動尋找主頁的,需要自己指定。

 

現在說說出現的問題,RewriteRule ^(.*)$ /blog/$1 前部分 ^(.*)$ 將會匹配當前請求的url。
例如:請求網址是http://www.xxx.com/a.html,到底是匹配整個http://www.xxx.com/a.html,還是只匹配/a.html即反斜杠后面的成分,還是只匹配a.html。
答 案是:(根據RewriteBase規則規定,如果rewritebase 為/,將會匹配a.html,不帶前面的反斜杠,所以上條語句應該寫成RewriteRule ^(.*)$ blog/$1(不帶/),不過實際應用上帶上前面的反斜杠,也可以用,可能帶不帶都行。現在問題出來了,如果不設置rewritebase 為/ ,將會匹配整個網址http://www.xxx.com/a.html,顯然這是錯誤的,所以應該添加這條:RewiteBase /)有誤,自己測試通不過,所以確的應該是 RewriteRule 中的跳轉部分加上 http://協議

 

還有一個問題是,不能保證每個人輸入的網址都是小寫的,如果輸入大寫的呢,linux系統是區分大小寫的,所以應該在RewriteCond后添加[NC]忽略大小寫的。

至此,完整的語句應該是:

 

RewriteEngine On
RewiteBase / RewriteCond %{HTTP_HOST} ^(www\.)?xxx\.com$ [NC] RewriteCond %{REQUEST_URI} !^/blog/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ blog/$1 # 沒有輸入文件名的默認到到首頁 RewriteCond %{HTTP_HOST} ^(www\.)?xxx\.com$ [NC] RewriteRule ^(/)?$ blog/index.php [L]

 



以上來自www.cnblogs.com/adforce/archive/2012/11/23/2784664.html

 help.vit.cn/item/category/htaccess 和 lesca.me/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM