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 禁缓存:它是指向最新构建产物的入口,被缓存了用户就拿不到新版本。

观测云对照

SPA 前端"白屏/路由错乱"类投诉,很多其实发生在交付层:静态资源 404、index.html 被缓存成旧版。把 Nginx 访问日志接入观测云,按 URI 聚合 404——发版后 /assets/ 下 404 突增,多半是新 HTML 引用了旧资源(缓存不一致);配合 RUM 真实用户监控,前端加载失败、白屏率直接按版本维度呈现。

常见问题(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 前缀与前端请求路径是否对齐。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

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

立即开始

选择观测云版本

代码托管平台