AWS ALB子路径转发至Nginx时静态资源无法加载问题
核心问题
你遇到的问题本质是两个环节的路径不匹配:
- React打包生成的资源引用路径未带上
/v2前缀,导致浏览器请求的资源路径不在ALB的转发规则范围内; - ALB Ingress未配置路径重写,转发给Nginx的请求保留了
/v2前缀,而Nginx的文件存储路径并没有这个前缀,导致资源找不到。
具体原因拆解
React资源路径问题
如果你没在React的package.json里配置homepage字段,打包后的index.html里的静态资源引用会是绝对路径(比如/assets/index-xxx.js)。当用户访问https://your-domain/v2时,浏览器会直接请求https://your-domain/assets/index-xxx.js——这个路径不在ALB配置的/v2/*转发规则里,自然不会被转发到你的Nginx容器,返回404。ALB Ingress路径转发问题
即使你通过Nginx的sub_filter强行替换资源路径为/v2/assets/,ALB把/v2/assets/index-xxx.js转发给Nginx时,会完整传递这个路径。而你的Nginx配置里,root是/usr/share/nginx/html,请求/v2/assets/index-xxx.js会让Nginx去查找/usr/share/nginx/html/v2/assets/index-xxx.js,但实际文件存在/usr/share/nginx/html/assets/下,所以找不到。
修复步骤
1. 配置React打包路径
在React项目的package.json中添加homepage字段,让打包后的资源自动带上/v2前缀:
"homepage": "/v2"
重新打包后,index.html里的资源引用会变成/v2/assets/index-xxx.js,确保浏览器请求的路径符合ALB的转发规则。
2. 调整AWS ALB Ingress配置
给Ingress添加路径重写注解,将/v2前缀从请求路径中剥离后再转发给Nginx:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: your-react-ingress annotations: alb.ingress.kubernetes.io/rewrite-target: /$2 # 其他ALB相关注解(如负载均衡类型、安全组等)保持不变 spec: ingressClassName: alb rules: - host: your-domain.com http: paths: - path: /v2(/|$)(.*) pathType: ImplementationSpecific backend: service: name: your-nginx-service port: number: 80
这个配置会把/v2/assets/index-xxx.js重写为/assets/index-xxx.js传给Nginx,Nginx就能直接从root目录找到对应文件。
3. 简化Nginx配置
不需要复杂的location规则,只需要处理静态资源和单页应用的路由回退:
server { listen 80; root /usr/share/nginx/html; index index.html index.htm; # 静态资源缓存配置 location ~* \.(js|css|png|jpg|ico|svg)$ { expires 1d; access_log off; } # 单页应用路由处理,所有未匹配静态资源的请求返回index.html location / { try_files $uri $uri/ /index.html; } }
这个配置足够处理所有请求:静态资源直接返回,React路由请求回退到index.html。
内容的提问来源于stack exchange,提问作者vemund

