根因:浏览器路由和服务器路由不是一回事
Vue Router 的 history 模式由前端接管路径。用户从首页点击到 `/articles` 时,页面没有真正重新请求 HTML;但刷新后,浏览器会直接请求服务器上的 `/articles`。如果 Nginx 不知道这个路径应该回退到 `index.html`,就会按静态文件查找,找不到自然返回 404。
基础配置思路
主站单页应用通常需要 `try_files $uri $uri/ /index.html;`。但如果站点还有 `/api`、`/s/`、`/tools/json-formatter/` 这类真实静态目录或代理路径,就不能粗暴全部回退。API 要代理后端,SEO 静态页要直接走文件,只有主站前端路由才回退。
主站路由
首页、文章列表、后台入口等 Vue 路由回退到 `index.html`。
API 路由
`/api` 必须优先代理到后端,不能被前端回退吞掉。
静态专题
`/s/` 页面不存在时应该 404,不应回到 Vue 首页。
检查清单
先确认线上实际加载的是哪套 Nginx 配置,不要只看系统默认目录。再用 `curl -I` 分别检查 `/`、`/articles`、`/api/public/home`、`/sitemap.xml`、`/s/某专题/`。如果 `/sitemap.xml` 返回 HTML,要优先检查是否被 `/s` 前缀规则误匹配。
经验结论:单页应用回退要精确,真实静态页和 API 要排在前面。Nginx location 顺序比想象中更容易制造线上错觉。