Apache .htaccess檔案


.htaccess檔案提供了一種基於每個目錄進行組態更改的方法。

1. 為什麼/如何使用.htaccess

.htaccess檔案(或「分散式組態檔案」)提供了一種基於每個目錄進行組態更改的方法。包含一個或多個組態指令的檔案放在特定的文件目錄中,並且指令適用於該目錄及其所有子目錄。

註:如果要將.htaccess檔案呼叫為其他檔案,可以使用AccessFileName指令更改檔案名。例如,如果您希望呼叫檔案.config,則可以將以下內容放入伺服器組態檔案中:

AccessFileName ".config"

通常,.htaccess檔案使用與主組態檔案相同的語法。可以在這些檔案中放置的內容由AllowOverride指令決定。該指令在類別中指定了在.htaccess檔案中找到的指令將被遵守的指令。如果.htaccess檔案中允許指令,則該指令的文件將包含Override部分,指定AllowOverride中必須包含的值,以便允許該指令。

2. 什麼時候使用/不使用.htaccess檔案

通常,只有在無法存取主伺服器組態檔案時才應使用.htaccess檔案。例如,有一種常見的誤解,即使用者身份驗證應始終在.htaccess檔案中完成,並且在最近幾年,另一種誤解是mod_rewrite指令必須放在.htaccess檔案中。這根本不是那麼回事。您可以將使用者身份驗證組態放在主伺服器組態中,事實上,這是執行操作的首選方式。同樣,mod_rewrite指令在許多方面在主伺服器組態中更好地工作。

.htaccess檔案應該用於內容提供者需要在每個目錄的基礎上對伺服器進行組態更改但在伺服器系統上沒有root存取許可權的情況。如果伺服器管理員不願意頻繁進行組態更改,則可能需要允許各個使用者自己在.htaccess檔案中進行這些更改。例如,在ISP在一台計算機上託管多個使用者站點並希望其使用者能夠更改其組態的情況下尤其如此。

但是,通常,應盡可能避免使用.htaccess檔案。您考慮放入.htaccess檔案的任何組態都可以在主伺服器組態檔案的<Directory>部分中有效地進行。

避免使用.htaccess檔案有兩個主要原因。

第一個是表現。當AllowOverride設定為允許使用.htaccess檔案時,httpd將在每個目錄中查詢.htaccess檔案。因此,允許.htaccess檔案會導致效能下降,無論您是否真正使用它們。此外,每次請求文件時都會載入.htaccess檔案。

還要注意,httpd必須在所有更高階別的目錄中查詢.htaccess檔案,以便擁有必須應用的完整指令。因此,如果從目錄/www/htdocs/example請求檔案,httpd必須查詢以下檔案:

/.htaccess
/www/.htaccess
/www/htdocs/.htaccess
/www/htdocs/example/.htaccess

因此,對於該目錄中的每個檔案存取,即使這些檔案都不存在,也有4個額外的檔案系統存取。(請注意,只有.htaccess檔案為/啟用時才會出現這種情況,通常情況並非如此。)

對於RewriteRule指令,在.htaccess上下文中,必須使用對目錄的每個請求重新編譯這些正規表示式,而在主伺服器組態上下文中,它們將被編譯一次並快取。此外,規則本身更複雜,因為必須解決每個目錄上下文和mod_rewrite帶來的限制。

第二個考慮因素是安全問題。您允許使用者修改伺服器組態,這可能導致無法控制的更改。仔細考慮是否要為使用者提供此許可權。另請注意,為使用者提供的許可權少於他們所需的許可權將導致其他技術支援請求。確保清楚地告訴使用者您給予他們的許可權級別。準確地指定你設定AllowOverride的內容,並將它們指向相關的文件,以後會為你節省很多困惑。

請注意,它完全等同於將.htaccess檔案放在包含指令的目錄/www/htdocs/example中,並將相同的指令放在主伺服器的Directory部分<Directory "/www/htdocs/example">中組態。

.htaccess檔案在目錄/www/htdocs/example之中:

AddType text/example ".exm"

httpd.conf檔案中的內容 -

<Directory "/www/htdocs/example">
    AddType text/example ".exm"
</Directory>

但是,將此組態放在伺服器組態檔案中將導致較少的效能損失,因為組態在httpd啟動時載入一次,而不是每次請求檔案時。

通過將AllowOverride指令設定為none,可以完全禁用.htaccess檔案的使用:

AllowOverride None

3. 如何應用指令

.htaccess檔案中找到的組態指令將應用於找到.htaccess檔案的目錄及其所有子目錄。但是,重要的是還要記住,目錄中可能存在.htaccess檔案。指令按照找到的順序應用。因此,特定目錄中的.htaccess檔案可能會覆蓋在目錄樹中較高位置的.htaccess檔案中找到的指令。反過來,那些可能已被覆蓋的指令更高,或者在主伺服器組態檔案本身中。

範例:

在目錄/www/htdocs/example1中,有一個.htaccess檔案,其中包含以下內容:

Options +ExecCGI

注意:必須具有AllowOverride Options才能允許在.htaccess檔案中使用Options指令。

在目錄/www/htdocs/example1/example2中,有一個.htaccess檔案,其中包含內容:

Options Includes

由於第二個.htaccess檔案,在目錄/www/htdocs/example1/example2中,不允許執行CGI,因為只有Options Includes有效,這完全覆蓋了可能已經存在的任何早期設定。

合併.htaccess與主組態檔案

.htaccess檔案可以覆蓋相應目錄的<Directory>片段,但是將被主組態檔案中的其他型別的組態片段覆蓋。即使存在AllowOverride設定,也可用於強制執行某些組態。例如,為了防止指令碼執行,同時允許在.htaccess中設定任何其他內容,您可以使用:

<Directory "/www/htdocs">
    AllowOverride All
</Directory>

<Location "/">
    Options +IncludesNoExec -ExecCGI
</Location>

4. 認證範例

有一種常見的誤解是您需要使用.htaccess檔案才能實現密碼驗證。將身份驗證指令放在主伺服器組態檔案的<Directory>部分中是實現此目的的首選方法,並且只有在您無權存取主伺服器組態檔案時才應使用.htaccess檔案。請參閱上文,了解何時應該和不應該使用.htaccess檔案。

話雖如此,如果您仍然認為需要使用.htaccess檔案,您可能會發現以下組態可能對您有用。

.htaccess檔案內容:

AuthType Basic
AuthName "Password Required"
AuthUserFile "/www/passwords/password.file"
AuthGroupFile "/www/passwords/group.file"
Require group admins

請注意,AllowOverride AuthConfig必須有效才能使這些指令生效。

5. 伺服器端包含範例

.htaccess檔案的另一個常見用途是為特定目錄啟用伺服器端包含。這可以通過以下組態指令完成,放置在所需目錄中的.htaccess檔案中:

Options +Includes
AddType text/html shtml
AddHandler server-parsed shtml

注意,AllowOverride OptionsAllowOverride FileInfo必須同時對這些指令生效才有效。

6. .htaccess檔案中的重寫規則

.htaccess檔案中使用RewriteRule時,請注意每個目錄的上下文會稍微改變一下。特別是,規則被認為是相對於當前目錄,而不是原始請求的URI。請考慮以下範例:

# In httpd.conf
RewriteRule "^/images/(.+)\.jpg" "/images/$1.png"

# In .htaccess in root dir
RewriteRule "^images/(.+)\.jpg" "images/$1.png"

# In .htaccess in images/
RewriteRule "^(.+)\.jpg" "$1.png"

在文件目錄的.htaccess中,從提供給RewriteRule的值中刪除前導斜槓,並在images子目錄中刪除/images/。因此,正規表示式也需要省略該部分。

7. CGI範例

最後,您可能希望使用.htaccess檔案來允許在特定目錄中執行CGI程式。這可以通過以下組態實現:

Options +ExecCGI
AddHandler cgi-script cgi pl

另外,如果希望在給定目錄中的所有檔案被認為是CGI程式,這可能具有以下組態來實現:

Options +ExecCGI
SetHandler cgi-script

請注意,AllowOverride OptionsAllowOverride FileInfo必須同時對這些指令生效才有效。