Nginx反向代理Docker部署的Swagger UI静态资源加载失败排查
故障根因定位
静态资源加载失败由两个明确的配置错误导致,和后端服务可用性、Swagger本身逻辑无关:
- 相对路径解析不符合预期:访问
https://www.webby.com/FileService返回的index.html中,脚本引用使用./swagger-ui-bundle.js这类相对路径,浏览器会直接将资源请求解析为https://www.webby.com/swagger-ui-bundle.js,根本不会匹配你写的/swagger/fileservice前缀的location规则,直接返回404。 - referer路由逻辑完全失效:首先你将
$host变量放在单引号字符串内做等值匹配,Nginx不会解析单引号内的变量,这个判断条件永远不会成立;其次referer头本身不稳定,部分浏览器、隐私插件、默认安全策略都会主动剥离referer,靠这个字段做路由必然出现漏匹配。
可直接复用的修正配置
删掉原有两段基于referer的if rewrite规则,按路径前缀统一做代理,不要仅用精确匹配代理index.html单文件:
server { listen 443 ssl http2; server_name www.webby.com; access_log /var/log/nginx/access.log; ssl_certificate /etc/ssl/yyyy.crt; ssl_certificate_key /etc/ssl/xxxx.key; ssl_protocols TLSv1.2; # FileService(441端口)代理 location /FileService/ { proxy_pass http://appy.com:441/swagger/; # 替换响应内的相对路径引用,避免资源请求跳转到根路径 sub_filter 'src="./' 'src="/FileService/'; sub_filter 'href="./' 'href="/FileService/'; sub_filter_once off; } # 兼容不带尾斜杠的访问请求 location = /FileService { return 302 /FileService/; } # PreProcess(442端口)代理 location /PreProcess/ { proxy_pass http://appy.com:442/swagger/; sub_filter 'src="./' 'src="/PreProcess/'; sub_filter 'href="./' 'href="/PreProcess/'; sub_filter_once off; } location = /PreProcess { return 302 /PreProcess/; } # 443端口的第三个API服务按相同规则扩展即可 # location /ThirdService/ { # proxy_pass http://appy.com:443/swagger/; # sub_filter 'src="./' 'src="/ThirdService/'; # sub_filter 'href="./' 'href="/ThirdService/'; # sub_filter_once off; # } # location = /ThirdService { # return 302 /ThirdService/; # } }
配置逻辑说明
- location路径和proxy_pass末尾都加尾斜杠后,Nginx会自动把
/FileService/xxx的请求转发到后端的/swagger/xxx,正好匹配后端Swagger的资源路径,不需要写复杂正则。 sub_filter会直接修改返回的HTML内容,把原页面里的相对路径资源引用替换成带服务前缀的路径,浏览器请求JS/CSS时会直接命中对应服务的location规则,不会再跑到域名根路径找资源。- 不带尾斜杠的路径直接302跳转到带尾斜杠的地址,从根源避免浏览器相对路径解析出错。
- 全程不依赖referer字段做路由,不会因为浏览器隐私策略出现请求漏匹配。
配置生效前先确认Nginx已自带
ngx_http_sub_module模块,在Nginx容器内执行nginx -V,输出中包含--with-http_sub_module即可正常使用sub_filter指令,官方默认Nginx镜像均自带该模块。
内容的提问来源于stack exchange,提问作者Yogi
相关产品推荐
相关产品推荐

