try_files $uri $uri/ /index.html 能解决 history 模式刷新 404,是因为它按序检查文件、目录是否存在,全部失败后内部静默转发至 /index.html,由前端路由接管渲染;非重定向,不改变 url。

直接在 location / 块里加 try_files $uri $uri/ /index.html; 就能解决大部分 history 模式刷新 404 问题,但必须确认 root 或 alias 指向正确、且没有更高优先级的 location 冲突。
为什么 try_files $uri $uri/ /index.html 能工作
它不是重定向,而是内部重写:Nginx 按顺序检查请求路径是否对应真实文件或目录,全部失败后才把请求“静默转发”给 /index.html,前端路由再接管渲染。
-
$uri查的是文件,比如/static/js/app.js能命中,正常返回 -
$uri/查的是目录,比如请求/admin且该路径下有index.html,就返回它(常用于子目录部署) -
/index.html是 fallback,只要前两项都不存在,就兜底到这里——这正是 SPA 需要的行为
子路径部署时别用 root,改用 alias
如果应用部署在 https://example.com/demo/ 下,而你写 location /demo { root /var/www/dist; },Nginx 会拼出 /var/www/dist/demo 去找文件,但实际资源在 /var/www/dist/ 目录下。
- 正确写法是:
location /demo { alias /var/www/dist/; }(注意末尾斜杠) - 对应的
try_files要同步调整为:try_files $uri $uri/ /demo/index.html; - 漏掉
alias末尾的/或写成root,会导致所有静态资源 404
容易被忽略的冲突点:正则 location 和精确匹配
Nginx 的 location 匹配有严格优先级,try_files 只在当前 location 块内生效。如果写了其他 location 覆盖了你的路由,try_files 就压根不执行。
- 比如同时存在
location ^~ /api(代理接口)和location /(SPA),没问题 - 但如果误加了
location ~ \.html$这类正则块,且它先于location /定义,就可能截断请求,导致/user被当成不存在的 .html 文件处理并直接 404 - 用
nginx -t验证配置后,再用curl -I http://localhost/user看响应头里的X-Accel-Redirect或实际返回内容,确认是否进了预期的 location
最常出问题的地方不在 try_files 本身,而在于它所在的 location 是否真正捕获了请求——多一层 location ~、少一个 alias 斜杠、或 root 路径多了一级目录,都会让整个 fallback 失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











