我有一个 Nginx 配置,其中我将请求代理到外部资源(s3 服务),但是当尝试访问特定静态文件时,Nginx 会回退到 try_files 指令,而不是代理请求。以下是简化的配置:
server {
listen 443 ssl;
server_name test.lightningmoment.com;
location /static/ {
proxy_pass https://haiskynology-test-web.oss-cn-hangzhou.aliyuncs.com/com.haiskynology.lightningmoment.web/test/build/static/;
proxy_set_header Host test-cdn.lightningmoment.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
proxy_pass https://haiskynology-test-web.oss-cn-hangzhou.aliyuncs.com/com.haiskynology.lightningmoment.web/test/build/;
proxy_set_header Host test-cdn.lightningmoment.com;
try_files $uri $uri/ /index.html;
}
}
该文件logo64.png
存在于以下 OSS 路径中:
当我尝试访问https://test.lightningmoment.com/logo64.png时,会导致 Nginx 回退到 try_files 逻辑并提供 index.html 文件,而不是将请求代理到 OSS 服务器。
我确认该文件存在,并且可以使用如下手动代理配置直接访问:
location /logo64.png {
proxy_pass https://haiskynology-test-web.oss-cn-hangzhou.aliyuncs.com/com.haiskynology.lightningmoment.web/test/build/logo64.png;
proxy_set_header Host test-cdn.lightningmoment.com;
}
同样,除非我明确添加配置,否则我无法访问静态文件夹下的文件location /static/
。
我的问题:为什么对 /logo64.png 的请求会回退到 try_files?
我该如何修复 proxy_pass 以正确转发请求而不陷入 try_files 后备逻辑?
我可以采取哪些调试步骤来进一步诊断这个问题?
我预期用户以nginx作为第一层入口来访问React网站test.lightningmoment.com
,然后我想给它添加一个cdn。
提前致谢!
你有没有读过
try_files
指令文档?使用try_files
该proxy_pass
指令完全没有意义。如果请求的文件在本地可用,为什么要将请求代理到其他后端?每个请求最终都会到达特定位置,每个位置有且仅有一个内容处理程序
..._pass
。除非通过其中一个指令(proxy_pass
、fastcgi_pass
、uwsgi_pass
等)明确指定内容处理程序,否则将隐式使用默认静态内容处理程序。也就是说,如果您
proxy_pass
为根位置指定内容处理程序,则永远不会使用静态内容处理程序。您可能想要实现的是本地处理静态文件请求,如果本地找不到该文件,则将请求代理到 CDN。可以使用以下配置来实现:
(我们不能
proxy_pass
在命名位置内的指令中使用 URI 部分,因此我使用rewrite ... break
指令更改上游请求 URI。)或者,将其与 React Router 混合:
(这里,我们拦截
404 Not Found
来自 CDN 上游的 HTTP 错误并使用/index.html
URI 作为后备,假设请求 URI 是 React 路由而不是静态文件名。)但是,我不会称其为一种绝妙的方法,因为每次页面刷新时,当前路由与根路由不同,都会导致
proxy_pass
对 CDN 的额外调用。您到底想实现什么?除了 之外,您还有其他文件夹中的静态文件吗
/static/
?PS上述示例中的不同
try_files
指令(try_files $uri ...
vs )是故意使用的。try_files $uri $uri/ ...
根据 OP 评论更新
如果您计划将所有前端文件放到 S3 服务器上,则以下更简单的配置应该有效: