Nginx 如何把所有请求都指向单个 HTML 页面?

Nginx 所有请求回退到单个 HTML(SPA 路由支持):try_files $uri $uri/ /index.html 配置;静态资源例外处理、history 路由 404 问题、缓存建议与 FAQ。

最佳实践
Nginx 如何把所有请求都指向单个 HTML 页面?封面

用 try_files 回退到入口页——这是单页应用(SPA)history 路由的标准 Nginx 配置:

server {
    listen 80;
    server_name example.com;
    root /var/www/myspa;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

含义:先按 URI 找真实文件 → 再找目录 → 都找不到就返回 /index.html,由前端路由接管。

为什么需要它

SPA(React/Vue/Angular)的路由在浏览器里完成:/user/42 这个路径在服务器上并不存在对应文件。直接访问或刷新这种 URL 时,若不做回退,Nginx 老老实实返回 404——这就是"SPA 刷新就 404"的经典问题。try_files 把所有"找不到"的路径兜底给 index.html,让 JS 路由决定渲染什么。

生产环境完整版

server {
    listen 80;
    server_name example.com;
    root /var/www/myspa/dist;
    index index.html;

    # 静态资源:存在即返回,长缓存(构建产物带 hash 才安全)
    location /assets/ {
        try_files $uri =404;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # API 请求别回退给 index.html,反代到后端
    location /api/ {
        proxy_pass http://backend:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # 其余全部回退到入口页
    location / {
        try_files $uri $uri/ /index.html;
    }

    # index.html 本身不缓存,保证发版即生效
    location = /index.html {
        add_header Cache-Control "no-cache";
    }
}

要点:

  • API 和静态资源要单独分流,不能一律回退——否则 404 的接口请求会返回 HTML,客户端解析出错还以为是后端问题。
  • index.html 禁缓存:它是指向最新构建产物的入口,被缓存了用户就拿不到新版本。

上线后分别测试前端深层路由和不存在的资源地址,确认 HTML 回退没有把资源 404 伪装成 200。若 Nginx 日志已通过 DataKit接入观测云,可按 /assets/ 路径检查发布时段的失败请求,再核对 HTML 引用与服务器上的资源文件;访问日志本身不能确认浏览器是否白屏。

常见问题(FAQ)

Q:配置了 try_files 还是 404?
A:按序排查:root 路径对吗(dist 目录别指漏)?index.html 文件在吗?Nginx 用户对该路径有读权限吗(403 会伪装成别的问题)?

Q:hash 路由(/#/path)需要这个配置吗?
A:不需要。hash 部分不发给服务器,/ 永远能命中 index.html。只有 history 模式(无 # 的干净 URL)才需要回退配置。

Q:回退后接口返回 HTML 导致前端报错?
A:说明 API 请求没被 /api/ location 拦截而落进了回退规则。检查 location 前缀与前端请求路径是否对齐。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台