HTACCESS 伪静态书写规则
2019獨角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
.htaccess是什么
.htaccess文件(或者"分布式配置文件")提供了針對目錄改變配置的方法, 即,在一個特定的文檔目錄中放置一個包含一個或多個指令的文件, 以作用于此目錄及其所有子目錄。作為用戶,所能使用的命令受到限制。管理員可以通過Apache的AllowOverride指令來設(shè)置。
概述來說,htaccess文件是Apache服務(wù)器中的一個配置文件,它負(fù)責(zé)相關(guān)目錄下的網(wǎng)頁配置。通過htaccess文件,可以幫我們實現(xiàn):網(wǎng)頁301重定向、自定義404錯誤頁面、改變文件擴展名、允許/阻止特定的用戶或者目錄的訪問、禁止目錄列表、配置默認(rèn)文檔等功能。
啟用.htaccess,需要修改httpd.conf,啟用AllowOverride,并可以用AllowOverride限制特定命令的使用。如果需要使用.htaccess以外的其他文件名,可以用AccessFileName指令來改變。例如,需要使用.config ,則可以在服務(wù)器配置文件中按以下方法配置:AccessFileName .config 。
籠統(tǒng)地說,.htaccess可以幫我們實現(xiàn)包括:文件夾密碼保護、用戶自動重定向、自定義錯誤頁面、改變你的文件擴展名、封禁特定IP地址的用戶、只允許特定IP地址的用戶、禁止目錄列表,以及使用其他文件作為index文件等一些功能。
?
工作原理
????? .htaccess文件(或者"分布式配置文件")提供了針對每個目錄改變配置的方法,即在一個特定的目錄中放置一個包含指令的文件,其中的指令作用于此目錄及其所有子目錄。
說明:
如果需要使用.htaccess以外的其他文件名,可以用AccessFileName指令來改變。例如,需要使用.config ,則可以在服務(wù)器配置文件中按以下方法配置:
AccessFileName .config
通常,.htaccess文件使用的配置語法和主配置文件一樣。AllowOverride指令按類別決定了.htaccess文件中哪些指令才是有效的。如果一個指令允許在.htaccess中使用,那么在本手冊的說明中,此指令會有一個覆蓋項段,其中說明了為使此指令生效而必須在AllowOverride指令中設(shè)置的值。
?
(不)使用.htaccess文件的場合
????? 一般情況下,不應(yīng)該使用.htaccess文件,除非你對主配置文件沒有訪問權(quán)限。有一種很常見的誤解,認(rèn)為用戶認(rèn)證只能通過.htaccess文件實現(xiàn),其實并不是這樣,把用戶認(rèn)證寫在主配置文件中是完全可行的,而且是一種很好的方法。
.htaccess文件應(yīng)該被用在內(nèi)容提供者需要針對特定目錄改變服務(wù)器的配置而又沒有root權(quán)限的情況下。如果服務(wù)器管理員不愿意頻繁修改配置,則可以允許用戶通過.htaccess文件自己修改配置,尤其是ISP在同一個機器上運行了多個用戶站點,而又希望用戶可以自己改變配置的情況下。
雖然如此,一般都應(yīng)該盡可能地避免使用.htaccess文件。任何希望放在.htaccess文件中的配置,都可以放在主配置文件的<Directory>段中,而且更高效。
避免使用.htaccess文件有兩個主要原因。
首先是性能。如果AllowOverride啟用了.htaccess文件,則Apache需要在每個目錄中查找.htaccess文件,因此,無論是否真正用到,啟用.htaccess都會導(dǎo)致性能的下降。另外,對每一個請求,都需要讀取一次.htaccess文件。
還有,Apache必須在所有上級的目錄中查找.htaccess文件,以使所有有效的指令都起作用(參見指令的生效),所以,如果請求/www/htdocs/example中的頁面,Apache必須查找以下文件:
/.htaccess /www/.htaccess /www/htdocs/.htaccess /www/htdocs/example/.htaccess
總共要訪問4個額外的文件,即使這些文件都不存在。(注意,這可能僅僅由于允許根目錄"/"使用.htaccess ,雖然這種情況并不多。)
??????其次是安全。這樣會允許用戶自己修改服務(wù)器的配置,這可能會導(dǎo)致某些意想不到的修改,所以請認(rèn)真考慮是否應(yīng)當(dāng)給予用戶這樣的特權(quán)。但是,如果給予用戶較少的特權(quán)而不能滿足其需要,則會帶來額外的技術(shù)支持請求,所以,必須明確地告訴用戶已經(jīng)給予他們的權(quán)限,說明AllowOverride設(shè)置的值,并引導(dǎo)他們參閱相應(yīng)的說明,以免日后生出許多麻煩。
注意,在/www/htdocs/example目錄下的.htaccess文件中放置指令,與在主配置文件中<Directory /www/htdocs/example>段中放置相同指令,是完全等效的。
????? /www/htdocs/example目錄下的.htaccess文件的內(nèi)容:
AddType text/example .exm
httpd.conf文件中摘錄的內(nèi)容:
<Directory /www/htdocs/example>
AddType text/example .exm
</Directory>
但是,把配置放在主配置文件中更加高效,因為只需要在Apache啟動時讀取一次,而不是在每次文件被請求時都讀取。
將AllowOverride設(shè)置為none可以完全禁止使用.htaccess文件:
AllowOverride None
?
指令的作用范圍
.htaccess文件中的配置指令作用于.htaccess文件所在的目錄及其所有子目錄,但是很重要的、需要注意的是,其上級目錄也可能會有.htaccess文件,而指令是按查找順序依次生效的,所以一個特定目錄下的.htaccess文件中的指令可能會覆蓋其上級目錄中的.htaccess文件中的指令,即子目錄中的指令會覆蓋父目錄或者主配置文件中的指令。
?
疑難解答
????? 如果在.htaccess文件中的某些指令不起作用,可能有多種原因。
最常見的原因是AllowOverride指令沒有被正確設(shè)置,必須確保沒有對此文件區(qū)域設(shè)置 AllowOverride None 。有一個很好的測試方法,就是在.htaccess文件隨便增加點無意義的垃圾內(nèi)容,如果服務(wù)器沒有返回了一個錯誤消息,那么幾乎可以斷定設(shè)置了 AllowOverride None 。
在訪問文檔時,如果收到服務(wù)器的出錯消息,應(yīng)該檢查Apache的錯誤日志,可以知道.htaccess文件中哪些指令是不允許使用的,也可能會發(fā)現(xiàn)需要糾正的語法錯誤。
?
.htaccess工具
不會寫的朋友,在這介紹一款很不錯.htaccess的重定向—URL重寫工具rewriting-tool
--------------------------------------------------------------------------------
htaccess語法教程
RewriteEngine?On RewriteCond?%{HTTP_HOST}?^(www\.)?xxx\.com$ RewriteCond?%{REQUEST_URI}?!^/blog/RewriteCond?%{REQUEST_FILENAME}?!-f RewriteCond?%{REQUEST_FILENAME}?!-d RewriteRule?^(.*)$?/blog/$1#?沒有輸入文件名的默認(rèn)到到首頁RewriteCond?%{HTTP_HOST}?^(www\.)?xxx\.com$ RewriteRule?^(/)?$?blog/index.php?[L]
下面我開始解說一下上面的意思:
【RewriteEngine?On】
表示重寫引擎開,關(guān)閉off,作用就是方便的開啟或關(guān)閉以下的語句,這樣就不需要一條一條的注釋語句了。
【RewriteCond?%{HTTP_HOST} ^(www\.)?xxx\.com$】
這是重寫條件,前面%{HTTP_HOST}表示當(dāng)前訪問的網(wǎng)址,只是指前綴部分,格式是www.xxx.com不包括“http://”和“/”,^表示 字符串開始,$表示字符串結(jié)尾,\.表示轉(zhuǎn)義的. ,如果不轉(zhuǎn)義也行,推薦轉(zhuǎn)義,防止有些服務(wù)器不支持,?表示前面括號www\.出現(xiàn)0次或1次,這句規(guī)則的意思就是如果訪問的網(wǎng)址是xxx.com或者 www.xxx.com就執(zhí)行以下的語句,不符合就跳過。
【RewriteCond %{REQUEST_URI} !^/blog/】
也是重寫條件,%{REQUEST_URI}表示訪問的相對地址,就是相對根目錄的地址,就是域名/后面的成分,格式上包括最前面的“/”,!表示非,這句語句表示訪問的地址不以/blog/開頭,只是開頭^,沒有結(jié)尾$
【RewriteCond %{REQUEST_FILENAME} !-f】
【RewriteCond %{REQUEST_FILENAME} !-d】
這兩句語句的意思是請求的文件或路徑是不存在的,如果文件或路徑存在將返回已經(jīng)存在的文件或路徑
【RewriteRule?^(.*)$ /blog/$1】
重寫規(guī)則,最重要的部分,意思是當(dāng)上面的RewriteCond條件都滿足的時候,將會執(zhí)行此重寫規(guī)則,^(.*)$是一個正則表達的 匹配,匹配的是當(dāng)前請求的URL,^(.*)$意思是匹配當(dāng)前URL任意字符,.表示任意單個字符,*表示匹配0次或N次(N>0),后面 /blog/$1是重寫成分,意思是將前面匹配的字符重寫成/blog/$1,這個$1表示反向匹配,引用的是前面第一個圓括號的成分,即^(.*)$中 的.* ,其實這兒將會出現(xiàn)一個問題,后面討論。
【RewriteCond %{HTTP_HOST} ^(www\.)?xxx\.com$】
【RewriteRule ^(/)?$ blog/index.php [L]】
這兩句的意思是指請求的host地址是www.xxx.com是,如果地址的結(jié)尾只有0個或者1個“/”時,將會重寫到子目錄下的主頁,我猜想這主要因為重寫后的地址是不能自動尋找主頁的,需要自己指定。
現(xiàn)在說說出現(xiàn)的問題,RewriteRule ^(.*)$ /blog/$1 前部分 ^(.*)$ 將會匹配當(dāng)前請求的url。
例如:請求網(wǎng)址是http://www.xxx.com/a.html,到底是匹配整個http://www.xxx.com/a.html,還是只匹配/a.html即反斜杠后面的成分,還是只匹配a.html。
答案是:根據(jù)RewriteBase規(guī)則規(guī)定,如果rewritebase 為/,將會匹配a.html,不帶前面的反斜杠,所以上條語句應(yīng)該寫成RewriteRule ^(.*)$ blog/$1(不帶/),不過實際應(yīng)用上帶上前面的反斜杠,也可以用,可能帶不帶都行。現(xiàn)在問題出來了,如果不設(shè)置rewritebase 為/ ,將會匹配整個網(wǎng)址http://www.xxx.com/a.html,顯然這是錯誤的,所以應(yīng)該添加這條:RewiteBase /
還有一個問題是,不能保證每個人輸入的網(wǎng)址都是小寫的,如果輸入大寫的呢,linux系統(tǒng)是區(qū)分大小寫的,所以應(yīng)該在RewriteCond后添加[NC]忽略大小寫的。
至此,完整的語句應(yīng)該是:
RewriteEngine?OnRewiteBase?/RewriteCond?%{HTTP_HOST}?^(www\.)?xxx\.com$?[NC] RewriteCond?%{REQUEST_URI}?!^/blog/RewriteCond?%{REQUEST_FILENAME}?!-f RewriteCond?%{REQUEST_FILENAME}?!-d RewriteRule?^(.*)$?blog/$1#?沒有輸入文件名的默認(rèn)到到首頁RewriteCond?%{HTTP_HOST}?^(www\.)?xxx\.com$?[NC] RewriteRule?^(/)?$?blog/index.php?[L]
如果后面還繼續(xù)有語句的,就不應(yīng)該加上最后的[L],因為這是表示最后一條語句的意思。
防盜鏈的語句,同樣需要添加RewiteBase /,如下:
如果后面還繼續(xù)有語句的,就不應(yīng)該加上最后的[L],/error/daolian.gif為別人盜鏈時顯示的圖片。
?
下面附上簡單的語法規(guī)則和flags
【RewriteCond語法】
RewriteCond TestString CondPattern [flags]
rewritecond的其他用法:
"-d"(目錄)
將TestString視為一個路徑名并測試它是否為一個存在的目錄。
"-f"(常規(guī)文件)
將TestString視為一個路徑名并測試它是否為一個存在的常規(guī)文件。
"-s"(非空的常規(guī)文件)
將TestString視為一個路徑名并測試它是否為一個存在的、尺寸大于0的常規(guī)文件。
"-l"(符號連接)
將TestString視為一個路徑名并測試它是否為一個存在的符號連接。
"-x"(可執(zhí)行)
將TestString視為一個路徑名并測試它是否為一個存在的、具有可執(zhí)行權(quán)限的文件。該權(quán)限由操作系統(tǒng)檢測。
"-F"(對子請求存在的文件)
檢查TestString是否為一個有效的文件,而且可以在服務(wù)器當(dāng)前的訪問控制配置下被訪問。它使用一個內(nèi)部子請求來做檢查,由于會降低服務(wù)器的性能,所以請謹(jǐn)慎使用!
"-U"(對子請求存在的URL)
檢查TestString是否為一個有效的URL,而且可以在服務(wù)器當(dāng)前的訪問控制配置下被訪問。它使用一個內(nèi)部子請求來做檢查,由于會降低服務(wù)器的性能,所以請謹(jǐn)慎使用!
【RewriteRule語法:】
RewriteRule Pattern Substitution [flags]
【flags】
"chain|C"(鏈接下一規(guī)則)
此標(biāo)記使當(dāng)前規(guī)則與下一個規(guī)則相鏈接。它產(chǎn)生這樣的效果:如果一個規(guī)則被匹配,則繼續(xù)處理其后繼規(guī)則,也就是這個標(biāo)記不起作用;如果該規(guī)則不被匹配,則其后繼規(guī)則將被跳過。比如,在一個目錄級規(guī)則中執(zhí)行一個外部重定向時,你可能需要刪除”.www”(此處不應(yīng)該出現(xiàn)”.www”)。
"cookie|CO=NAME:VAL:domain[:lifetime[:path]]"(設(shè)置cookie)
在客戶端設(shè)置一個cookie。cookie的名稱是NAME,值是VAL。domain是該cookie的域,比如".apache.org",可選的lifetime是cookie的有效期(分鐘),可選的path是cookie的路徑。
"env|E=VAR:VAL"(設(shè)置環(huán)境變量)
此標(biāo)記將環(huán)境變量VAR的值為VAL,VAL可以包含可擴展的正則表達式反向引用($N和%N)。此標(biāo)記可以多次使用以設(shè)置多個變量。這些變量可以在其后許多情況下被間接引用,通常是在XSSI(<!–#echo var=”VAR”–>)或CGI($ENV{"VAR"})中,也可以在后繼的RewriteCond指令的CondPattern參數(shù)中通過%{ENV:VAR}引用。使用它可以記住從URL中剝離的信息。
"forbidden|F"(強制禁止URL)
強制禁止當(dāng)前URL,也就是立即反饋一個HTTP響應(yīng)碼403(被禁止的)。使用這個標(biāo)記,可以鏈接若干個RewriteConds來有條件地阻塞某些URL。
"gone|G"(強制廢棄URL)
強制當(dāng)前URL為已廢棄,也就是立即反饋一個HTTP響應(yīng)碼410(已廢棄的)。使用這個標(biāo)記,可以標(biāo)明頁面已經(jīng)被廢棄而不存在了。
"handler|H=Content-handler"(強制指定內(nèi)容處理器)
強自制定目標(biāo)文件的內(nèi)容處理器為Content-handler。例如,用來模擬mod_alias模塊的ScriptAlias指令,以強制映射文件夾內(nèi)的所有文件都由”cgi-script”處理器處理。
"last|L"(結(jié)尾規(guī)則)
立即停止重寫操作,并不再應(yīng)用其他重寫規(guī)則。它對應(yīng)于Perl中的last命令或C語言中的break命令。這個標(biāo)記用于阻止當(dāng)前已被重寫的URL被后繼規(guī)則再次重寫。例如,使用它可以重寫根路徑的URL("/")為實際存在的URL(比如:"/e/www/")。
"next|N"(從頭再來)
重新執(zhí)行重寫操作(從第一個規(guī)則重新開始)。此時再次進行處理的URL已經(jīng)不是原始的URL了,而是經(jīng)最后一個重寫規(guī)則處理過的URL。它對應(yīng)于Perl中的next命令或C語言中的continue命令。此標(biāo)記可以重新開始重寫操作(立即回到循環(huán)的開頭)。但是要小心,不要制造死循環(huán)!
"nocase|NC"(忽略大小寫)
它使Pattern忽略大小寫,也就是在Pattern與當(dāng)前URL匹配時,"A-Z"和"a-z"沒有區(qū)別。
"noescape|NE"(在輸出中不對URI進行轉(zhuǎn)義)
此標(biāo)記阻止mod_rewrite對重寫結(jié)果應(yīng)用常規(guī)的URI轉(zhuǎn)義規(guī)則。 一般情況下,特殊字符("%", "$", ";"等)會被轉(zhuǎn)義為等值的十六進制編碼("%25′, "%24′, "%3B"等)。此標(biāo)記可以阻止這樣的轉(zhuǎn)義,以允許百分號等符號出現(xiàn)在輸出中,比如:
RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE]
可以使"/foo/zed轉(zhuǎn)向到一個安全的請求"/bar?arg=P1=zed"。
"nosubreq|NS"(不對內(nèi)部子請求進行處理)
在當(dāng)前請求是一個內(nèi)部子請求時,此標(biāo)記強制重寫引擎跳過該重寫規(guī)則。比如,在mod_include試圖搜索目錄默認(rèn)文件(index.xxx)時,Apache會在內(nèi)部產(chǎn)生子請求。對于子請求,重寫規(guī)則不一定有用,而且如果整個規(guī)則集都起作用,它甚至可能會引發(fā)錯誤。所以,可以用這個標(biāo)記來排除某些規(guī)則。
使用原則:如果你為URL添加了CGI腳本前綴,以強制它們由CGI腳本處理,但對子請求處理的出錯率(或者資源開銷)很高,在這種情況下,可以使用這個標(biāo)記。
"proxy|P"(強制為代理)
此標(biāo)記使替換成分被內(nèi)部地強制作為代理請求發(fā)送,并立即中斷重寫處理,然后把處理移交給mod_proxy模塊。你必須確保此替換串是一個能夠被mod_proxy處理的有效URI(比如以http://hostname開頭),否則將得到一個代理模塊返回的錯誤。使用這個標(biāo)記,可以把某些遠程成分映射到本地服務(wù)器域名空間,從而增強了ProxyPass指令的功能。
注意:要使用這個功能,必須已經(jīng)啟用了mod_proxy模塊。
"passthrough|PT"(移交給下一個處理器)
此標(biāo)記強制重寫引擎將內(nèi)部request_rec結(jié)構(gòu)中的uri字段設(shè)置為filename字段的值,這個小小的修改使得RewriteRule指令的輸出能夠被(從URI轉(zhuǎn)換到文件名的)Alias, ScriptAlias, Redirect等指令進行后續(xù)處理[原文:This flag is just a hack to enable post-processing of the output of RewriteRule directives, using Alias, ScriptAlias, Redirect, and other directives from various URI-to-filename translators.]。舉一個能說明其含義的例子: 如果要將/abc重寫為/def, 然后再使用mod_alias將/def轉(zhuǎn)換為/ghi,可以這樣:
RewriteRule ^/abc(.*) /def$1 [PT]
Alias /def /ghi
如果省略了PT標(biāo)記,雖然將uri=/abc/…重寫為filename=/def/…的部分運作正常,但是后續(xù)的mod_alias在試圖將URI轉(zhuǎn)換到文件名時會遭遇失效。
注意:如果需要混合使用多個將URI轉(zhuǎn)換到文件名的模塊時,就必須使用這個標(biāo)記。。此處混合使用mod_alias和mod_rewrite就是個典型的例子。
"qsappend|QSA"(追加查詢字符串)
此標(biāo)記強制重寫引擎在已有的替換字符串中追加一個查詢字符串,而不是簡單的替換。如果需要通過重寫規(guī)則在請求串中增加信息,就可以使用這個標(biāo)記。
"redirect|R?[=code]"(強制重定向)
若Substitution以http://thishost[:thisport]/(使新的URL成為一個URI)開頭,可以強制性執(zhí)行一個外部重定向。如果沒有指定code,則產(chǎn)生一個HTTP響應(yīng)碼302(臨時性移動)。如果需要使用在300-400范圍內(nèi)的其他響應(yīng)代碼,只需在此指定即可(或使用下列符號名稱之一:temp(默認(rèn)), permanent, seeother)。使用它可以把規(guī)范化的URL反饋給客戶端,如將”/~”重寫為”/u/”,或始終對/u/user加上斜杠,等等。
注意:在使用這個標(biāo)記時,必須確保該替換字段是一個有效的URL。否則,它會指向一個無效的位置!并且要記住,此標(biāo)記本身只是對URL加上http://thishost[:thisport]/前綴,重寫操作仍然會繼續(xù)進行。通常,你還會希望停止重寫操作而立即重定向,那么就還需要使用"L'標(biāo)記。
"skip|S=num"(跳過后繼規(guī)則)
此標(biāo)記強制重寫引擎跳過當(dāng)前匹配規(guī)則之后的num個規(guī)則。它可以模擬if-then-else結(jié)構(gòu):最后一個規(guī)則是then從句,而被跳過的skip=N個規(guī)則是else從句。注意:它和"chain|C"標(biāo)記是不同的!
"type|T=MIME-type"(強制MIME類型)
強制目標(biāo)文件的MIME類型為MIME-type,可以用來基于某些特定條件強制設(shè)置內(nèi)容類型。比如,下面的指令可以讓.php文件在以.phps擴展名調(diào)用的情況下由mod_php按照PHP源代碼的MIME類型(application/x-httpd-php-source)顯示:
RewriteRule ^(.+\.php)s$ $1 [T=application/x-httpd-php-source]
轉(zhuǎn)載于:https://my.oschina.net/miaowang/blog/219922
總結(jié)
以上是生活随笔為你收集整理的HTACCESS 伪静态书写规则的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 利用SSH端口转发功能实现X转发
- 下一篇: 让 sphinx 支持中文、日文和韩文