.htaccess 完全指南 2026:功能详解与常用代码示例
.htaccess Guide 2026: What It Does and the Most Useful Code Examples
目录
.htaccess 是什么?它在 Apache 上如何工作
.htaccess(超文本访问文件)是 Apache Web 服务器的目录级配置文件,允许网站管理员在不修改主配置文件 httpd.conf 的情况下,针对特定目录自定义服务器行为,且修改立即生效无需重启服务器。
文件名以点(.)开头,使其成为 Unix/Linux 系统上的隐藏文件。Apache 在每次收到 HTTP 请求时,都会从根目录开始逐层读取 .htaccess 文件,直到目标文件所在目录为止。这意味着每次修改都能立即反映,无任何停机时间。
.htaccess 能实现的功能非常丰富:URL 重定向与重写、强制 HTTPS 访问、目录密码保护、IP 封锁、设置缓存响应头、自定义错误页面、防止图片盗链、创建友好 URL(Pretty URL),以及通过 php_value 调整 PHP 配置参数。
创建 .htaccess 文件的方法:创建一个纯文本文件,命名为 .htaccess(以点开头,无扩展名),放置于网站根目录或需要控制的子目录中。子目录中的规则仅对该目录及其子目录生效,不会影响上级目录。
# 基本 .htaccess 示例 — 启用 mod_rewrite
Options +FollowSymLinks
RewriteEngine On
# 设置默认首页文件
DirectoryIndex index.php index.html index.htm
重要提示:.htaccess 仅适用于 Apache Web 服务器。如果您的主机使用 Nginx 或 Windows IIS,.htaccess 文件将完全无效。兼容 Apache 的 LiteSpeed 服务器同样支持 .htaccess,许多基于 cPanel 的主机使用 LiteSpeed 时也可正常使用。
URL 重定向与 301 跳转
通过 .htaccess 进行 URL 重定向是最常见的应用场景之一,无论是将旧页面迁移到新 URL、整站域名迁移,还是修复用户访问的错误链接,.htaccess 都能轻松实现。
301 永久重定向告知搜索引擎该 URL 已永久迁移,搜索引擎会将原始页面的权重(链接权益)传递给目标 URL 并更新索引。适用于永久性 URL 变更、域名迁移或网站结构调整。
302 临时重定向告知搜索引擎保留原始 URL 的索引,不传递权重。适用于 A/B 测试、短期促销活动或维护期间的临时跳转。
# 单页面 301 永久重定向
Redirect 301 /old-page.html /new-page.html
# 302 临时重定向
Redirect 302 /promo /sale
# 整个目录的重定向
Redirect 301 /blog/ /articles/
# 跳转至外部域名
Redirect 301 /partner https://example.com/partner
# 使用 mod_rewrite 实现灵活的 301(支持正则表达式)
RewriteEngine On
RewriteRule ^old-page\.html$ /new-page.html [R=301,L]
# 将 /products/ 下所有 URL 重定向至 /shop/
RewriteRule ^products/(.*)$ /shop/$1 [R=301,L]
需要注意重定向链和重定向循环的问题。重定向链(A → B → C)会增加延迟;重定向循环(A → B → A)会导致浏览器显示"重定向次数过多"错误,使页面完全无法访问。部署前务必使用重定向检测工具进行验证。
强制 HTTPS 与 www 跳转配置
2026 年,为网站启用 HTTPS 是不可妥协的基本要求。Google 将 HTTPS 作为排名因素,Chrome 等浏览器会在 HTTP 页面上显示"不安全"警告,直接影响访客信任度。如果您的主机已提供免费 SSL 证书(如 Let's Encrypt),通过 .htaccess 强制 HTTPS 跳转是最简单的实现方式。
除 HTTPS 外,还需统一域名格式——选择 https://example.com 或 https://www.example.com 其中一种,并将另一种重定向过去。两种格式同时可访问会造成重复内容问题,分散 SEO 权重。
# 强制所有请求使用 HTTPS
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# 强制 HTTPS 并将 www 重定向至非 www(推荐组合)
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]
# 或分两步写,逻辑更清晰:
# 第一步:强制 HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# 第二步:www 跳转至非 www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]
若网站部署在 Cloudflare 或其他反向代理后面,%{HTTPS} 变量可能始终为 "off",即使访客使用 HTTPS 也如此。此时应改为检测转发协议头:
# 适用于 Cloudflare 或负载均衡器后面的站点
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
强制 HTTPS 后,建议添加 HSTS 响应头,告知浏览器始终通过 HTTPS 连接,即使用户输入的是 http:// 也会自动使用 HTTPS,无需再经过重定向:
# 添加 HSTS 响应头(有效期 1 年)
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</IfModule>
保护文件与目录安全
通过 .htaccess 实现安全防护涵盖多个层面:为管理目录设置密码保护、禁止直接访问敏感文件(配置文件、数据库备份、日志文件),以及关闭目录列表功能(防止访客看到目录结构)。
目录密码保护需要先使用 htpasswd 命令行工具或在线生成器创建 .htpasswd 文件,建议将其存放于 Web 根目录之外:
# 使用 HTTP Basic Auth 保护目录
AuthType Basic
AuthName "受限区域"
AuthUserFile /home/user/private/.htpasswd
Require valid-user
# 仅允许特定用户访问
Require user admin
禁止访问敏感文件类型,防止访客通过浏览器直接下载配置文件、SQL 转储或日志文件:
# 禁止访问敏感扩展名文件
<FilesMatch "\.(env|sql|log|bak|config|ini|sh)$">
Require all denied
</FilesMatch>
# 保护 .htaccess 和 .htpasswd 文件本身
<FilesMatch "^\.ht">
Require all denied
</FilesMatch>
# 禁止在上传目录中执行 PHP 文件
<Directory /var/www/html/uploads>
<FilesMatch "\.php$">
Require all denied
</FilesMatch>
</Directory>
关闭目录列表,防止 Apache 在目录无索引文件时自动显示文件列表:
# 全站关闭目录列表
Options -Indexes
# 将管理页面限制到特定 IP 访问
<Files "admin.php">
Require ip 203.150.100.50
Require ip 192.168.1.0/24
</Files>
浏览器缓存与 Gzip 压缩加速
通过 .htaccess 配置浏览器缓存和 Gzip 压缩,是在 Apache 主机上提升网站速度最简单、效果最显著的优化手段之一。无需修改任何程序代码,即可改善 PageSpeed 评分和 Core Web Vitals 核心指标。
Gzip/Deflate 压缩在传输前对 HTML、CSS、JavaScript、JSON 等文本资源进行压缩,可将文件体积减少 60–80%,对移动端慢速网络用户效果尤为明显:
# 通过 mod_deflate 启用 Gzip 压缩
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/json
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE font/woff2
</IfModule>
浏览器缓存(mod_expires)让浏览器在本地缓存静态资源,减少重复访问时的 HTTP 请求数量:
<IfModule mod_expires.c>
ExpiresActive On
# 图片 — 缓存 1 年(很少变更)
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
# 字体 — 缓存 1 年
ExpiresByType font/woff2 "access plus 1 year"
ExpiresByType font/woff "access plus 1 year"
# CSS/JS — 缓存 1 个月
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
# HTML — 缓存 1 小时(内容更新频繁)
ExpiresByType text/html "access plus 1 hour"
</IfModule>
# 添加 Cache-Control 响应头
<IfModule mod_headers.c>
<FilesMatch "\.(css|js|jpg|jpeg|png|gif|webp|ico|woff|woff2)$">
Header set Cache-Control "max-age=2592000, public"
</FilesMatch>
</IfModule>
使用较长缓存时间时,需注意缓存更新问题。若更新了 CSS 或 JS 文件但文件名未变,访客仍会看到缓存的旧版本。解决方法是在 URL 后附加版本号(如 style.css?v=2.1)或在文件名中加入哈希值(如 style.abc123.css)。
自定义错误页面 404 403 500
自定义错误页面将 Apache 默认的纯文本错误屏幕替换为具有品牌风格、用户友好的页面,即使在出错时也能帮助访客找到所需内容,减少用户流失。
最常见的 HTTP 错误代码:404(未找到 — 请求的 URL 不存在)、403(禁止访问 — 无权访问)、500(服务器内部错误 — 服务器端问题)、503(服务不可用 — 服务器过载或维护中)。
# 定义自定义错误页面
ErrorDocument 400 /errors/400.html
ErrorDocument 401 /errors/401.html
ErrorDocument 403 /errors/403.html
ErrorDocument 404 /errors/404.html
ErrorDocument 500 /errors/500.html
ErrorDocument 503 /errors/503.html
# 或重定向至完整 URL
ErrorDocument 404 https://example.com/not-found.html
# 维护模式:将所有流量重定向至维护页面
# (您自己的 IP 除外)
RewriteEngine On
RewriteCond %{REMOTE_ADDR} !^203\.150\.100\.50$
RewriteCond %{REQUEST_URI} !/maintenance.html$
RewriteRule ^(.*)$ /maintenance.html [R=302,L]
一个优质的 404 页面应包含:网站导航栏、搜索框、热门页面链接以及简短的说明文字。定期检查 404 错误日志非常重要,突然增多的 404 通常意味着网站内部存在断链,需要及时修复。
500 错误页面应使用纯静态 HTML,不依赖任何 PHP 或数据库,因为 500 错误往往在 PHP 或数据库出现问题时发生。若 500 页面本身依赖 PHP,将会显示空白页面,造成最差的用户体验。
封锁 IP 地址与防止盗链
通过 .htaccess 封锁 IP 可以有效阻止暴力破解攻击、恶意爬虫和内容抓取工具。防盗链功能则防止其他网站直接引用您服务器上的图片,避免消耗您的带宽而您却得不到任何收益。
在 Apache 2.4+ 中封锁 IP(当前主流版本):
# 封锁单个 IP
Require not ip 192.168.1.100
# 封锁多个 IP
<RequireAll>
Require all granted
Require not ip 192.168.1.100
Require not ip 10.0.0.5
Require not ip 203.0.113.25
</RequireAll>
# 封锁整个 /24 子网(256 个 IP)
Require not ip 192.168.1
# 仅允许特定 IP 访问(拒绝其他所有人)
Require ip 203.150.100.50
Require ip 192.168.0.0/16
# 使用 mod_rewrite 封锁(兼容旧版 Apache)
RewriteEngine On
RewriteCond %{REMOTE_ADDR} ^192\.168\.1\.100$
RewriteRule ^ - [F,L]
防止图片盗链,避免外部网站直接嵌入您服务器上的图片:
# 防止盗链 — 显示占位图片
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?yourdomain\.com [NC]
RewriteRule \.(jpg|jpeg|png|gif|webp|svg)$ /images/hotlink-forbidden.png [NC,L]
# 或返回 403 禁止访问
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?yourdomain\.com [NC]
RewriteRule \.(jpg|jpeg|png|gif|webp)$ - [F,NC,L]
注意:严格的 Referer 检查可能会在用户直接在新标签页中打开图片(空 Referer)或使用注重隐私的浏览器(不发送 Referer 头)时误封图片显示。请充分测试,确保规则不会影响您自己网站上的图片正常展示。
常见错误与调试方法
.htaccess 文件中的任何语法错误都会立即导致整个目录出现 500 内部服务器错误,网站完全无法访问。了解常见的错误模式,能帮您节省大量排查时间。
常见错误类型:
- 语法错误:任何指令中的拼写错误都会导致整个文件失效,引发 500 错误。部署前务必使用在线 .htaccess 语法验证工具检查。
- AllowOverride 为 None:如果服务器管理员将
AllowOverride None设置在 httpd.conf 中,.htaccess 中的所有规则都会被静默忽略,需联系主机商开启。 - mod_rewrite 未加载:在 Ubuntu/Debian 上运行
a2enmod rewrite启用模块,或检查 phpinfo() 确认 mod_rewrite 状态。 - 规则顺序错误:Apache 从上到下处理规则,第一个匹配的规则生效(除非使用
[L]标志)。更具体的规则应放在通用规则前面。 - 末尾斜杠差异:
/folder和/folder/在 Apache 中是不同的 URL,编写 RewriteRule 时需明确指定。 - 文件编码问题:.htaccess 文件必须保存为不带 BOM 的 UTF-8 格式,换行符使用 Unix 格式(LF),而非 Windows 格式(CRLF)。
调试步骤建议:
# Apache 2.4 启用 RewriteLog 调试
LogLevel alert rewrite:trace3
# 检查 Apache 配置语法
apachectl -t
# 查看 Apache 错误日志
tail -f /var/log/apache2/error.log
推荐调试流程:始终先在测试环境中验证,逐条添加规则并分别测试,通过 Apache 错误日志获取具体错误信息,使用浏览器开发者工具(Network 标签页)检查 HTTP 状态码和重定向链,利用在线 htaccess 测试工具模拟规则匹配效果。
性能提示:如果您使用 VPS 或独立服务器并需要极致性能,建议将 .htaccess 中的规则迁移至 httpd.conf 的 <VirtualHost> 区块中,并设置 AllowOverride None。Apache 启动时只读取 httpd.conf 一次,可避免每次请求读取 .htaccess 文件带来的 I/O 开销。