Apache HTTP Server 版本 2.4
相關模組 | 相關指令 |
---|---|
在決定要針對特定請求提供哪個檔案時,httpd 的預設行為會是取得此請求的 URL 路徑(URL 中主機名稱與埠號之後的部分),並將其加在組態檔中指定的 DocumentRoot
的結尾。因此, DocumentRoot
底下的檔案與目錄構成從 Web 可見的基本文件樹狀結構。
例如,若已將 DocumentRoot
設定為 /var/www/html
,則會針對 http://www.example.com/fish/guppies.html
的請求提供檔案 /var/www/html/fish/guppies.html
給請求端的用戶端。
如果請求目錄(亦即以 /
結尾的路徑),則該目錄中提供的檔案由 DirectoryIndex
指令定義。例如,如果 DocumentRoot
已設定如上述範例,而您要設定
DirectoryIndex index.html index.php
那麼請求 http://www.example.com/fish/
會使 httpd 嘗試提供檔案 /var/www/html/fish/index.html
。如果該檔案不存在,它會接著嘗試提供檔案 /var/www/html/fish/index.php
。
如果這兩個檔案都不存在,下一步是嘗試提供目錄索引,但前提是 mod_autoindex
已載入並已設定允許執行。
httpd 也支援 虛擬主機,使伺服器能夠接收多個主機的請求。在這種情況下,可以針對每個虛擬主機指定不同的 DocumentRoot
,或者,可以使用模組 mod_vhost_alias
中提供的指令,根據請求的 IP 地址或主機名稱動態決定提供內容的適當位置。
必須在主伺服器設定檔(httpd.conf
)中設定 DocumentRoot
指令,也可能為您建立的每個額外 虛擬主機 設定一次。
經常發生需要允許網路存取檔案系統中不完全位於 DocumentRoot
之下部分的情況。httpd 提供了數種不同的方法來達成這個目的。在 Unix 系統中,符號連結可以讓檔案系統的其他部分置於 DocumentRoot
之下。出於安全考量,httpd 僅在相關目錄的 Options
設定包含 FollowSymLinks
或 SymLinksIfOwnerMatch
的情況下,才會遵循符號連結。
或者,Alias
指令會將檔案系統的任何部分對應到網路空間中。例如,對於
Alias "/docs" "/var/web"
URL http://www.example.com/docs/dir/file.html
會從 /var/web/dir/file.html
提供服務。 ScriptAlias
指令的工作原理相同,但所有位於目標路徑的內容都被視為 CGI 程式碼。
對於需要額外彈性的情況,您可以使用 AliasMatch
和 ScriptAliasMatch
指令來執行強大的、基於 正規表示式 的匹配和取代。例如:
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 系統中,特定使用者的家目錄可以稱為 ~user/
。模組 mod_userdir
將這個概念延伸至網路,允許使用下列 URL 方式存取每個使用者的家目錄中的檔案。
http://www.example.com/~user/file.html
基於安全考量,不適合從網路直接存取使用者的家目錄。因此,UserDir
指令會指定使用者家目錄底下的目錄,其中存放著網頁檔案。使用預設設定 Userdir public_html
,上述 URL 會對應至類似 /home/user/public_html/file.html
的目錄中的檔案,其中 /home/user/
是使用者家目錄,如 /etc/passwd
中指定。
另有其他數種 Userdir
指令格式,可用於 /etc/passwd
沒有包含家目錄所在位置的系統。
有些人會覺得 "~" 符號 (通常在網頁上編碼為 %7e
) 很奇怪,並偏好使用替代字串來表示使用者目錄。mod_userdir 不支援此功能。不過,如果使用者的家目錄採用常規結構,就可以使用 AliasMatch
指令來達成預期效果。例如,若要讓 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"
上述章節討論的設定指令會指示 httpd 從檔案系統中的特定位置取得內容,並將內容傳回給客戶端。有時,將內容要求的客戶端告知請求的內容位於不同的 URL 位置,並指示客戶端使用新的 URL 提出新的請求,會更合適。這樣的動作稱為重新導向,並由 Redirect
指令實作。例如,如果 DocumentRoot
底下 /foo/
目錄中的內容已移至新的目錄 /bar/
中,您可以指示客戶端在新的位置請求內容,如下所示
Redirect permanent "/foo/" "http://www.example.com/bar/"
這會將任何從 /foo/
開始的 URL 路徑重新導向至 www.example.com
伺服器上的相同 URL 路徑,並將 /foo/
改為 /bar/
。您可以將客戶端重新導向至任何伺服器,不只是原始伺服器。
httpd 也提供 RedirectMatch
指令,用於更複雜的改寫問題。例如,若要將網站首頁的請求重新導向至另一個網站,但保留所有其他請求,請使用下列設定檔
RedirectMatch permanent "^/$" "http://www.example.com/startpage.html"
或者,若要暫時將一個網站上的所有網頁重新導向至另一個網站上的特定網頁,請使用下列指令
RedirectMatch temp ".*" "http://othersite.example.com/startpage.html"
httpd 也允許您將遠端文件引入至本機伺服器的 URL 空間中。此技術稱為「反向代理」,這是因為網頁伺服器就像一個代理伺服器,從遠端伺服器擷取文件並將其傳回給用戶端。它與一般的(順向)代理不同,因為在用戶端看來,文件是從反向代理伺服器產生的。
在下列範例中,當用戶端要求在 /foo/
目錄下的文件時,伺服器會從 internal.example.com
上的 /bar/
目錄中擷取那些文件,並將其傳回給用戶端,就好像文件來自本機伺服器一樣。
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
會將伺服器設定為擷取適當的文件,而 ProxyPassReverse
指令會改寫源自 internal.example.com
的重新導向,以便針對本機伺服器上的適當目錄。類似地,ProxyPassReverseCookieDomain
和 ProxyPassReverseCookiePath
會改寫後端伺服器所設定的 Cookie。
但請務必注意,文件中的連結並不會被改寫。因此,internal.example.com
上的任何絕對連結都會導致用戶端中斷代理伺服器,並直接從 internal.example.com
進行請求。您可以使用
針對網頁進行傳送給用戶端的內容進行修改(及其他內容)。mod_substitute
Substitute "s/internal\.example\.com/www.example.com/i"
若要針對 HTML 和 XHTML 中的連結執行更精密的改寫,
模組也會同時提供。它允許您建立需要改寫的 URL 清單,以便處理複雜的代理場景。mod_proxy_html
當需要更強大的替換時,
所提供的改寫引擎會很有用。此模組所提供的指令可以使用請求的特徵,例如瀏覽器類型或來源 IP 位址,來決定從何處傳遞內容。此外,mod_rewrite 可以使用外部資料庫檔案或程式來決定如何處理請求。改寫引擎能夠執行上述討論的三種類型的對應:內部重新導向(別名)、外部重新導向和代理。許多使用 mod_rewrite 的實際範例會在 mod_rewrite 詳細文件中進行討論。mod_rewrite
不可避免地,會要求尋找在檔案系統中找不到相符檔案的 URL。這可能會出於幾個原因發生。在某些情況下,可能是將文件從一個位置移動到另一個位置造成的。如果發生這種情況,最好使用 網址重新導向 來通知客戶端該資源的新位置。這樣,您可以確保舊書籤和連結能夠繼續運作,即使該資源已移至新位置也不受影響。
產生「檔案未找到」錯誤的另一個常見原因是直接在瀏覽器或 HTML 連結中意外輸入錯誤的 URL。httpd 提供模組 mod_speling
(sic) 來協助解決此問題。當此模組啟動時,它會攔截「檔案未找到」錯誤,並尋找具有類似檔名的資源。如果找到其中一個檔案,mod_speling 會傳送 HTTP 重新導向到客戶端,告知它正確的位置。如果找到多個「接近」的檔案,系統會向客戶端提供可用替代方案清單。
mod_speling 特別有用的功能是不分大小寫比較檔名。對於使用者不知道 URL 和 unix 檔案系統區分大小寫特性的系統,這項功能很有幫助。但是,使用 mod_speling 來執行比偶爾更正 URL 更多的動作可能會增加伺服器負擔,因為每個「不正確」的請求都會接著產生一個 URL 重新導向和一個來自客戶端的新請求。
mod_dir
提供 FallbackResource
,可用於將虛擬 URI 轉換至真實資源,然後再提供服務。實作「前端控制項」時,這是非常有用的 mod_rewrite
替代方案
如果所有尋找內容的嘗試都失敗,httpd 會傳回 HTTP 狀態碼 404(未找到檔案)的錯誤頁面。此頁面的外觀由 ErrorDocument
指令控管,並可以在 自訂錯誤回應 文件中討論的靈活方式進行自訂。
可用於 URL 轉換的其他模組包括
mod_actions
- 根據要求方法或資源 MIME 類型,將請求轉換至 CGI 腳本。mod_dir
- 提供將尾隨斜線轉換至索引檔案(例如 index.html
)的基本轉換。mod_imagemap
- 根據使用者按一下內嵌於 HTML 文件中圖像的位置,將請求轉換至 URL。mod_negotiation
- 根據語言或內容壓縮等客戶端偏好選取適當文件。