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 Options
和AllowOverride 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 Options
和AllowOverride FileInfo
必须同时对这些指令生效才有效。