关键在于root拼接路径与try_files逐项匹配:root指定基础前缀,$uri拼接后查找文件,$uri/查目录,最后一项必须是存在的/index.html或内部URI,确保文件存在且权限可读。

用 root 指令配合 try_files 实现“文件不存在时返回默认页”,关键在于理解 root 的路径拼接逻辑和 try_files 的逐项匹配机制。不是简单写个 try_files $uri /index.html; 就能生效,必须确保路径解析正确、默认页存在、且不触发意外重定向或 404。
明确 root 的作用是拼接路径,不是设置绝对根目录
root 指令指定的是“基础路径前缀”,Nginx 会把请求 URI(如 /a/b/c.js)拼接到该路径后,形成实际文件路径。例如:
-
root /var/www/html;+ 请求/js/app.js→ 查找/var/www/html/js/app.js -
root /data/site;+ 请求/→ 查找/data/site/(即尝试读取该目录下的 index 文件,或由try_files控制)
注意:root 不影响 try_files 中的相对路径(如 /index.html),它仍以 root 值为基准解析。
try_files 的最后一项是“兜底”,必须是存在的文件或内部 URI
try_files 按顺序检查每个参数是否对应真实文件(或目录)。最后一项不能是纯路径别名,而应是:一个存在的静态文件(如 /index.html),或一个内部 location(如 =404 或 @fallback)。常见错误是写成 try_files $uri /; —— 这会引发循环查找,因 / 又触发当前 location,可能 500 或无限重定向。
- ✅ 正确:
try_files $uri $uri/ /index.html;(优先找文件,再找目录,最后回退到/var/www/html/index.html) - ✅ 安全兜底:
try_files $uri $uri/ @vue; # 然后定义 location @vue { rewrite ^(.*)$ /index.html break; } - ❌ 危险:
try_files $uri /;(无终止条件,易死循环)
确保默认页真实存在,且权限可读
即使配置语法正确,若 /index.html 在 root 目录下不存在,或 Nginx 工作进程(如 www-data)无读取权限,仍会返回 404 或 403。建议:
- 用
ls -l /var/www/html/index.html确认文件存在且属主/组可读 - 测试直接访问
http://your-domain.com/index.html是否能打开 - 若用单页应用(SPA),通常只需一个
index.html,其余路由由前端 JS 处理,因此兜底到它即可
完整可用示例(SPA 场景)
以下配置让所有非静态资源请求都落到 index.html,由前端路由接管:
server {
listen 80;
server_name example.com;
root /var/www/my-spa;
index index.html;
<pre class="brush:php;toolbar:false;">location / {
try_files $uri $uri/ /index.html;
}
# 可选:显式处理静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}}
说明:$uri 匹配精确文件(如 /app.js),$uri/ 匹配目录(如请求 /blog/ 且该目录存在),最后 /index.html 是绝对路径(相对于 root),作为最终 fallback。


















