
本文详解如何通过 .htaccess 实现:访问根路径(/)时自动加载 template/index.html,同时将 /api/* 请求精准路由至 api.php,避免冲突、目录列表暴露及重写逻辑失效问题。
本文详解如何通过 `.htaccess` 实现:访问根路径(`/`)时自动加载 `template/index.html`,同时将 `/api/*` 请求精准路由至 `api.php`,避免冲突、目录列表暴露及重写逻辑失效问题。
在 Apache 的 URL 重写实践中,一个常见误区是混淆 REQUEST_URI 的格式特征与正则匹配逻辑,导致根路径重写失效(如返回 403 Forbidden 或显示目录索引)。例如,当期望 domain.com/ 显示 template/index.html,却始终看到“Index of /”页面,根本原因在于重写规则未正确捕获空路径,或被后续更宽泛的规则覆盖。
✅ 正确的根路径重写规则
REQUEST_URI 始终以 / 开头(如根路径为 /,而非空字符串),因此条件 RewriteCond %{REQUEST_URI} ^$ 永远不成立。应直接使用 RewriteRule 的锚定模式 ^$ 匹配空路径(即仅匹配 /):
RewriteRule ^$ template/index.html [L]
- ^$ 表示“开头即结尾”,严格匹配根 URI /;
- [L] 标志至关重要:表示“Last”,即匹配后立即终止重写流程,防止后续规则干扰;
- 此规则必须置于所有泛匹配规则之前(推荐放在 .htaccess 开头),确保优先执行。
✅ 精准路由 API 请求(推荐方案)
原规则 RewriteRule ^(.*)$ api.php [QSA] 过于宽泛,会劫持所有请求(包括静态资源、根路径等),且存在安全隐患与性能损耗。更合理的设计是仅重写 /api/ 开头的路径:
# 禁用 MultiViews(防止 mod_negotiation 干扰 .php 文件解析)
Options -MultiViews
# 1. 根路径 → template/index.html
RewriteRule ^$ template/index.html [L]
# 2. /api/* → api.php(保留原始路径作为参数)
RewriteRule ^api/(.*)$ api.php?path=$1 [QSA,L]
# 3. 其他不存在的文件/目录 → 可选:404 或 fallback(非必需)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ 404.html [L]? 示例效果:
- GET / → 渲染 template/index.html
- GET /api/users → 转发至 api.php?path=users,PHP 中可通过 $_GET['path'] 获取 users
- GET /css/app.css → 直接返回静态文件(因 -f 条件满足,跳过重写)
⚠️ 关键注意事项
- Options -MultiViews 必须启用:否则 Apache 可能尝试内容协商(如将 /api 解析为 api.php),导致重写失效或 500 错误;
- *避免 `.泛匹配根路径**:RewriteRule . template/index.html中的.匹配任意单字符(除换行符),无法匹配/,且无^$` 锚定,逻辑错误;
- [L] 不可省略:缺少该标志时,即使匹配根路径,后续 api.php 规则仍可能被执行,造成意外交互;
- 静态资源优先原则:Apache 默认优先服务真实存在的文件(!-f)和目录(!-d),因此 template/index.html 若真实存在,无需额外条件即可被正确响应——但显式重写可确保即使启用 DirectoryIndex 也保持行为一致。
✅ 总结:最佳实践结构
完整的、健壮的 .htaccess 应按以下顺序组织:
Options -MultiViews
RewriteEngine On
# Step 1: Root → index.html
RewriteRule ^$ template/index.html [L]
# Step 2: API endpoints only
RewriteRule ^api/(.*)$ api.php?path=$1 [QSA,L]
# Step 3: Optional — Fallback for missing resources (keep after API rule)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ 404.html [L]此结构清晰分离关注点,兼顾安全性、可维护性与性能,是现代 PHP 前后端分离项目(如 SPA + REST API)的标准 Apache 配置范式。











