react-router配合Nginx Ingress非根路径刷新出现404或白屏问题求解
问题根因
你遇到的两个错误本质都是SPA前端路由的经典问题:
- 非根路径刷新404:服务端没有对应前端路由的路径资源,默认返回404
- 加配置后出现
Unexpected token '<':你加的重写规则把静态资源(js/css/图片)的请求也重定向到了返回index.html,浏览器尝试把html内容当js解析就会报这个错。
可行解决方案
方案一:后端服务层处理(更稳定,推荐)
这种方案和你本地开发逻辑一致,不需要改动Ingress的复杂配置,出错概率低。
- 修正Ingress配置,删除所有多余注解
你之前加的rewrite-target、configuration-snippet、use-regex都会和后端服务的逻辑冲突,全部删除,最简配置如下:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: myApp-ingress annotations: kubernetes.io/ingress.class: nginx cert-manager.io/cluster-issuer: letsencrypt-prod spec: tls: - hosts: - my.app.com secretName: myApp-tls rules: - host: "my.app.com" http: paths: - pathType: Prefix path: / backend: service: name: myApp port: number: 80
注意:请确认你的Service配置正确,80端口的targetPort必须指向容器暴露的3000端口,否则请求根本不会到达你的应用服务,直接返回404。
- 确认后端服务配置
你贴的Express代码是正确的,先本地打包后启动服务测试:访问http://localhost:3000/path1刷新确认不会404,再部署到集群即可。
如果你用http-server替代Express,启动命令必须加--history-api-fallback参数才能支持前端路由刷新:
CMD ["npx", "http-server", "./dist", "-p", "3000", "--history-api-fallback"]
- 排查前端打包配置
确认webpack配置里的publicPath设置为/(绝对路径),不要用相对路径./,否则非根路径刷新时浏览器会从当前子路径请求静态资源,导致资源加载失败。
方案二:Ingress层处理(无需改动后端服务)
如果你不想改后端服务,直接在Ingress层做路由重写,正确配置如下,不要用之前的try_files规则(Ingress层的nginx无法识别你容器内的静态资源路径,会把所有请求都重写到index.html):
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: myApp-ingress annotations: kubernetes.io/ingress.class: nginx cert-manager.io/cluster-issuer: letsencrypt-prod nginx.ingress.kubernetes.io/configuration-snippet: | # 只有请求的文件不存在时才重写到index.html,避免影响静态资源 if (!-e $request_filename) { rewrite ^(.*)$ /index.html break; } spec: tls: - hosts: - my.app.com secretName: myApp-tls rules: - host: "my.app.com" http: paths: - pathType: Prefix path: / backend: service: name: myApp port: number: 80
内容的提问来源于stack exchange,提问作者Thomas Colbert
相关产品推荐
相关产品推荐

