Apache 將url映射到文件

2021-10-13 18:21 更新

本文將介紹Apache HTTP Server如何使用請求的URL來確定從中提供文件的文件系統(tǒng)位置。

DocumentRoot

在決定為給定請求提供什么文件時,httpd的默認行為是獲取請求的URL-Path(主機名和端口后面的URL部分),并將其添加到配置文件中指定的DocumentRoot的末尾。因此,DocumentRoot下面的文件和目錄構(gòu)成了可從Web上看到的基本文檔樹。

例如,如果DocumentRoot設(shè)置為/var/www/html時,則對http://www.example.com/fish/guppies.html的請求會將文件/var/www/html/fish/guppies.html發(fā)送到請求客戶。

如果請求目錄(即以/結(jié)尾的路徑),則從該目錄提供的文件由DirectoryIndex指令定義。例如,如果DocumentRoot設(shè)置為/var/www/html/,則要設(shè)置:

DirectoryIndex index.html index.php
Shell

然后,對http://www.example.com/fish/的請求將導(dǎo)致httpd嘗試提供文件/var/www/html/fish/index.html。如果該文件不存在,它將接下來嘗試提供文件/var/www/html/fish/index.php。

如果這兩個文件都不存在,則下一步是嘗試提供目錄索引,加載mod_autoindex并配置為允許該目錄索引。

httpd還具有虛擬主機功能,服務(wù)器可以接收多個主機的請求。在這種情況下,可以為每個虛擬主機指定不同的DocumentRoot,或者,模塊mod_vhost_alias提供的指令可用于根據(jù)請求的IP地址或主機名動態(tài)確定從中提供內(nèi)容的適當(dāng)位置。

DocumentRoot之外的文件

通常情況下,必須允許Web訪問文件系統(tǒng)中嚴格不在DocumentRoot下的部分。httpd提供了幾種不同的方法來實現(xiàn)這一目標。在Unix系統(tǒng)上,符號鏈接可以將文件系統(tǒng)的其他部分帶到DocumentRoot下。出于安全原因,僅當(dāng)相關(guān)目錄的Options設(shè)置包括FollowSymLinks或SymLinksIfOwnerMatch時,httpd才會遵循符號鏈接。

或者,Alias指令將文件系統(tǒng)的任何部分映射到Web空間。例如,

Alias "/docs" "/var/web"
Shell

網(wǎng)址 http://www.example.com/docs/dir/file.html 將從/var/web/dir/file.html提供。ScriptAlias指令的工作方式相同,其附加效果是位于目標路徑的所有內(nèi)容都被視為CGI腳本。

對于需要額外靈活性的情況,可以使用AliasMatch和ScriptAliasMatch指令來執(zhí)行基于正則表達式的強大匹配和替換。例如,

ScriptAliasMatch "^/~([a-zA-Z0-9]+)/cgi-bin/(.+)"   "/home/$1/cgi-bin/$2"
Shell

將請求映射到http://example.com/~user/cgi-bin/script.cgi到路徑/home/user/cgi-bin/script.cgi,并將生成的文件視為CGI腳本。

用戶目錄

傳統(tǒng)上在Unix系統(tǒng)上,特定用戶的主目錄可以稱為~user/。模塊mod_userdir通過允許使用以下URL訪問每個用戶主目錄下的文件,將此想法擴展到Web。

http://www.example.com/~user/file.html
Shell

出于安全原因,從Web直接訪問用戶的主目錄是不合適的。因此,UserDir指令指定用戶主目錄下Web目錄所在的目錄。使用Userdir public_html的默認設(shè)置,上面的URL映射到/home/user/public_html/file.html等目錄中的文件,其中/home/user/是/etc/passwd中指定的用戶主目錄。

有些人發(fā)現(xiàn)~符號(通常在網(wǎng)絡(luò)上編碼為%7e)很尷尬,并且更喜歡使用替代字符串來表示用戶目錄。mod_userdir不支持此功能。但是,如果用戶的主目錄以常規(guī)方式構(gòu)造,則可以使用AliasMatch指令來實現(xiàn)所需的效果。例如,要將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/$3"
Shell

URL重定向

上面討論的配置指令告訴httpd從文件系統(tǒng)中的特定位置獲取內(nèi)容并將其返回給客戶端。有時,希望通知客戶端所請求的內(nèi)容位于不同的URL,并指示客戶端使用新URL發(fā)出新請求。這稱為重定向,由Redirect指令實現(xiàn)。例如,如果DocumentRoot下目錄/foo/的內(nèi)容被移動到新目錄/bar/,可以指示客戶端在新位置請求內(nèi)容,如下所示:

Redirect permanent "/foo/"   "http://www.example.com/bar/"
Shell

這會將從/foo/開始的任何URL-Path重定向到www.example.com服務(wù)器上的相同URL路徑,其中/bar/替換為/foo/。可以將客戶端重定向到任何服務(wù)器,而不僅僅是原始服務(wù)器。

httpd還提供了RedirectMatch指令,用于更復(fù)雜的重寫問題。例如,要將站點主頁的請求重定向到其他站點,但僅保留所有其他請求,請使用以下配置:

RedirectMatch permanent "^/$"    "http://www.example.com/startpage.html"
Shell

或者,要臨時將一個站點上的所有頁面重定向到另一個站點上的特定頁面,請使用以下命令:

RedirectMatch temp ".*"  "http://othersite.example.com/startpage.html"
Shell

反向代理

httpd還允許將遠程文檔帶入本地服務(wù)器的URL空間。此技術(shù)稱為反向代理,因為Web服務(wù)器通過從遠程服務(wù)器獲取文檔并將其返回到客戶端來充當(dāng)代理服務(wù)器。它與正常(轉(zhuǎn)發(fā))代理不同,因為對于客戶端,文檔似乎來自反向代理服務(wù)器。

在以下示例中,當(dāng)客戶端請求/foo/目錄下的頁面文檔時,服務(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/"
Shell

ProxyPass配置服務(wù)器以獲取相應(yīng)的文檔,而ProxyPassReverse指令重寫源自internal.example.com的重定向,以便它們定位到本地服務(wù)器上的相應(yīng)目錄。同樣,ProxyPassReverseCookieDomain和ProxyPassReverseCookiePath重寫由后端服務(wù)器設(shè)置的cookie。

但是,請務(wù)必注意,文檔中的鏈接不會被重寫。因此,internal.example.com上的任何絕對鏈接都將導(dǎo)致客戶端突破代理服務(wù)器并直接從internal.example.com請求。您可以使用mod_substitute在頁面中修改這些鏈接(以及其他內(nèi)容)。

Substitute "s/internal\.example\.com/www.example.com/i"
Shell

對于HTML和XHTML中鏈接的更復(fù)雜重寫,mod_proxy_html模塊也可用。它允許創(chuàng)建需要重寫的URL映射,以便可以處理復(fù)雜的代理方案。

重寫引擎

當(dāng)需要更強大的替換時,mod_rewrite提供的重寫引擎可能很有用。該模塊提供的指令可以使用請求的特征(例如瀏覽器類型或源IP地址)來決定從哪里提供內(nèi)容。此外,mod_rewrite可以使用外部數(shù)據(jù)庫文件或程序來確定如何處理請求。重寫引擎能夠執(zhí)行上面討論的所有三種類型的映射:內(nèi)部重定向(別名),外部重定向和代理。

文件未找到

不可避免地請求有時也會在文件系統(tǒng)中找不到匹配文件的URL。這可能由于幾個原因而發(fā)生。在某些情況下,它可能是將文檔從一個位置移動到另一個位置的結(jié)果。在這種情況下,最好使用URL重定向來通知客戶端資源的新位置。通過這種方式,即使資源位于新位置,您也可以確保舊書簽和鏈接繼續(xù)有效。

“找不到文件”錯誤的另一個常見原因是URL的直接錯誤輸入,無論是直接在瀏覽器中還是在HTML鏈接中。httpd提供模塊mod_speling(sic)來幫助解決這個問題。激活此模塊時,它將攔截“找不到文件”錯誤并查找具有類似文件名的資源。如果找到一個這樣的文件,mod_speling將向客戶端發(fā)送HTTP重定向,通知它正確的位置。如果找到幾個“關(guān)閉”文件,將向客戶提供可用備選列表。

mod_speling的一個特別有用的功能是,它將比較文件名而不考慮大小寫。這可以幫助用戶不了解URL和unix文件系統(tǒng)的區(qū)分大小寫特性的系統(tǒng)。但是,除了偶爾的URL更正之外,使用mod_speling可以在服務(wù)器上增加額外負載,因為每個“不正確”的請求后面都有URL重定向和來自客戶端的新請求。

mod_dir提供FallbackResource,可用于將虛擬URI映射到真實資源,然后為其提供服務(wù)。在實現(xiàn)’前端控制器’時,這是對mod_rewrite非常有用的替代品

如果查找內(nèi)容的所有嘗試都失敗,httpd將返回一個錯誤頁面,其中包含HTTP狀態(tài)代碼404(找不到文件)。此頁面的外觀由ErrorDocument指令控制,可以按照自定義錯誤響應(yīng)文檔中的討論以靈活的方式進行自定義。





以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號