?
Dieses Dokument verwendet PHP-Handbuch für chinesische Websites Freigeben
本文闡述Apache如何根據(jù)URL地址定位到文件在文件系統(tǒng)中的位置。
相關(guān)模塊 | 相關(guān)指令 |
---|---|
|
|
Apache根據(jù)請(qǐng)求定位文件的默認(rèn)操作是:取出URL路徑(即URL中主機(jī)名和端口后面的部分)附加到由DocumentRoot
指定的文件系統(tǒng)路徑后面。這樣就組成了在網(wǎng)上所看見(jiàn)的基本文件樹(shù)結(jié)構(gòu)。
如果服務(wù)器有多個(gè)虛擬主機(jī),則Apache會(huì)使用下述兩種方法之一:使用每個(gè)虛擬主機(jī)自己的DocumentRoot
來(lái)組成文件系統(tǒng)路徑,或者使用由mod_vhost_alias
提供的指令基于IP地址或主機(jī)名動(dòng)態(tài)地定位文件。
實(shí)際應(yīng)用中,經(jīng)常有必要允許網(wǎng)絡(luò)對(duì)DocumentRoot
以外的文件進(jìn)行訪問(wèn)。對(duì)此,Apache提供了多種方法,在Unix系統(tǒng)中,可以在文件系統(tǒng)的DocumentRoot
目錄下放置符號(hào)連接以訪問(wèn)其外部文件,考慮到安全問(wèn)題,這種方法僅在相應(yīng)目錄的Options
指令中設(shè)置了FollowSymLinks
或SymLinksIfOwnerMatch
時(shí)才有效。
另外,使用Alias
指令可以將文件系統(tǒng)的任何部分映射到網(wǎng)絡(luò)空間中。例如,這個(gè)命令
Alias /docs /var/web
可以把URL http://www.example.com/docs/dir/file.html
映射為/var/web/dir/file.html
。ScriptAlias
指令功能相似,而且使所有目標(biāo)路徑下的所有文件被視為CGI腳本。
AliasMatch
和ScriptAliasMatch
指令可以實(shí)現(xiàn)基于正則表達(dá)式的匹配和替換,以提供更大的靈活性。例如:
ScriptAliasMatch ^/~([a-zA-Z0-9]+)/cgi-bin/(.+) /home/$1/cgi-bin/$2
上述命令可以將http://example.com/~user/cgi-bin/script.cgi
映射到/home/user/cgi-bin/script.cgi
,并視之為CGI腳本。
在Unix系統(tǒng)中,一個(gè)特定用戶"user"的主目錄通常是"~user/
"模塊mod_userdir
在網(wǎng)絡(luò)上沿用了這個(gè)概念,允許使用URL訪問(wèn)位于各用戶主目錄下的文件,例如:
http://www.example.com/~user/file.html
出于安全原因,不應(yīng)該給予網(wǎng)絡(luò)用戶直接操作主目錄的權(quán)限,而應(yīng)該在用戶主目錄下新建一個(gè)目錄,把網(wǎng)絡(luò)文件放在這個(gè)新建的目錄中,并用UserDir
指令告訴服務(wù)器。缺省的用戶目錄設(shè)置是"Userdir public_html
",因此,上述例子中的URL會(huì)映射到/home/user/public_html/file.html
,其中/home/user/
是/etc/passwd
指定的用戶主目錄。
當(dāng)/etc/passwd
沒(méi)有指定主目錄,那就要用到Userdir
指令的另幾種形式。
有些人覺(jué)得符號(hào)"~"(時(shí)常會(huì)被編碼為%7e
)很別扭,希望用其他形式來(lái)表達(dá)用戶目錄。雖然模塊mod_userdir
并不支持,但是,如果合理規(guī)劃服務(wù)器上的用戶目錄,則還是有可能用AliasMatch
指令來(lái)達(dá)到這個(gè)目的。例如,如果希望將http://www.example.com/upages/user/file.html
映射到/home/user/public_html/file.html
,可以這樣使用AliasMatch
指令:
AliasMatch ^/upages/([a-zA-Z0-9]+)/?(.*) /home/$1/public_html/$2
上述指令都指示Apache返回給客戶文件系統(tǒng)的某個(gè)特定內(nèi)容,但是有時(shí)候,需要通知客戶其請(qǐng)求的內(nèi)容位于其他URL,并使客戶產(chǎn)生新的對(duì)其他URL的請(qǐng)求,這種機(jī)制稱(chēng)為重定向(redirection),可以用Redirect
指令實(shí)現(xiàn)。例如:如果DocumentRoot
的目錄/foo/
被轉(zhuǎn)移到了/bar/
,則可以這樣引導(dǎo)客戶訪問(wèn)新的位置:
Redirect permanent /foo/ http://www.example.com/bar/
這個(gè)命令重定向任何以/foo/
開(kāi)頭的URL路徑到位于同一個(gè)服務(wù)器www.example.com
的/bar/
。當(dāng)然,可以重定向到任何其它服務(wù)器,而不僅僅是原來(lái)的那個(gè)。
Apache還提供了RedirectMatch
指令來(lái)解決復(fù)雜的重定向問(wèn)題。例如,要重定向?qū)φ军c(diǎn)主頁(yè)的請(qǐng)求到其他站點(diǎn),而保留其他所有請(qǐng)求,可以這樣配置:
RedirectMatch permanent ^/$ http://www.example.com/startpage.html
另一種方法是,暫時(shí)地重定向站點(diǎn)的所有頁(yè)面到一個(gè)特定頁(yè)面,如:
RedirectMatch temp .* http://othersite.example.com/startpage.html
Apache還允許將遠(yuǎn)程文檔納入本地服務(wù)器的網(wǎng)絡(luò)空間中,因?yàn)閃eb服務(wù)器扮演一個(gè)代理服務(wù)器的角色(從遠(yuǎn)程服務(wù)器取得文檔并返回給客戶),所以這種機(jī)制被稱(chēng)為反向代理(reverse proxying),不同于標(biāo)準(zhǔn)代理的是,在客戶看來(lái),他請(qǐng)求的文檔似乎原本就位于這個(gè)反向代理服務(wù)器上。
下例演示了當(dāng)客戶請(qǐng)求位于/foo/
目錄下的文檔時(shí),服務(wù)器從internal.example.com
的/bar/
目錄下取回文檔并返回給客戶,似乎文檔原本就在本地服務(wù)器上:
ProxyPass /foo/ http://internal.example.com/bar/
ProxyPassReverse /foo/ http://internal.example.com/bar/
ProxyPassReverseCookieDomain internal.example.com public.example.com
ProxyPassReverseCookiePath /foo/ /bar/
ProxyPass
指令使服務(wù)器正確地取回文檔,同時(shí),ProxyPassReverse
指令改變了起始于internal.example.com
的請(qǐng)求,使之指向本地服務(wù)器上的目錄。同樣,ProxyPassReverseCookieDomain
和ProxyPassReverseCookieDomain
指令將會(huì)改變后端服務(wù)器設(shè)置的cookie 。
需要注意的很重要的一點(diǎn)是,被取回的文檔中的連接是不會(huì)被改寫(xiě)的,因此,文檔中的所有絕對(duì)路徑連接會(huì)突破代理機(jī)制而直接從internal.example.com
取得。一個(gè)第三方模塊mod_proxy_html可以用于重寫(xiě)HTML和XHTML連接。
mod_rewrite
模塊提供了更強(qiáng)大的URL重寫(xiě)引擎,可以根據(jù)請(qǐng)求中諸如瀏覽器類(lèi)型、源IP地址等特征來(lái)決定最終提交給客戶的內(nèi)容,還可以使用外部數(shù)據(jù)庫(kù)或程序來(lái)決定如何處理一個(gè)請(qǐng)求,并可以執(zhí)行上述的所有三種映射:內(nèi)部重定向(aliases)、外部重定向、代理。許多實(shí)用程序都用到了這個(gè)模塊,詳細(xì)論述參見(jiàn):URL重寫(xiě)指南。
從URL到文件系統(tǒng)的匹配失敗是不可避免的,其產(chǎn)生原因有多種。有時(shí)是文檔被轉(zhuǎn)移了,對(duì)此最好是用URL重定向來(lái)引導(dǎo)用戶訪問(wèn)新的位置,這樣,雖然資源已經(jīng)轉(zhuǎn)移到新的位置,但是原來(lái)的書(shū)簽和連接仍然有效。
另一種常見(jiàn)的原因是瀏覽器地址欄或者HTML連接中的URL被拼寫(xiě)錯(cuò)了,Apache提供了mod_speling
模塊來(lái)幫助解決這個(gè)問(wèn)題,它會(huì)接管"File Not Found"錯(cuò)誤并查找相似文件,如果找到了唯一的一個(gè),則會(huì)重定向到這個(gè)文件,如果不止一個(gè),則會(huì)列一張表反饋給用戶。
mod_speling
的一個(gè)很有用的特性是,它可以忽略大小寫(xiě)查找文件,對(duì)不注意URL大小寫(xiě)的用戶和unix文件系統(tǒng)尤為實(shí)用。但是,糾正偶然的URL錯(cuò)誤會(huì)給服務(wù)器帶來(lái)額外的負(fù)擔(dān),因?yàn)槊看?不正確"的請(qǐng)求都將引發(fā)URL重定向和來(lái)自客戶的新請(qǐng)求。
如果所有的努力都失敗了,Apache會(huì)返回一個(gè)出錯(cuò)信息頁(yè)面,其狀態(tài)碼為"404"(文件沒(méi)找到),其頁(yè)面內(nèi)容取決于ErrorDocument
指令,并可以靈活地自定義其形式,詳見(jiàn):自定義錯(cuò)誤響應(yīng)。