Swagger UI在Nginx反向代理切换域名后页面空白求助
Swagger UI/Redoc反向代理后空白,静态资源加载失败问题排查
配置Swagger UI在/swagger/路径运行,切换域名前正常,改用Nginx反向代理后页面空白,/redoc/也存在同样问题。/ht/健康检查路径可正常访问,React前端应用本身运行正常,但Network面板中Swagger的CSS/JS文件返回"Javascript needs to be enabled to run this app",控制台报Uncaught SyntaxError: Unexpected token '<'。
配置文件
Nginx.conf
events { worker_connections 768; multi_accept on; } http { large_client_header_buffers 16 5120k; fastcgi_read_timeout 900; proxy_read_timeout 900; proxy_connect_timeout 900; proxy_send_timeout 900; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; server_tokens off; proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; include /etc/nginx/mime.types; default_type application/octet-stream; ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; gzip on; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; 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; proxy_set_header Host $http_host; proxy_intercept_errors on; server { client_max_body_size 250M; listen 80; server_name mysite.com; location /.well-known/acme-challenge/ { root /var/www/certbot; } location / { return 301 https://$host$request_uri; } } server { client_max_body_size 250M; listen 443 ssl; server_name mysite.com; ssl_certificate /etc/letsencrypt/live/mysite.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/mysite.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location / { proxy_pass http://mysite:3000/; proxy_redirect off; 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; proxy_set_header Host $http_host; proxy_intercept_errors on; } location /ht/ { proxy_pass http://mysite:8000/ht/; proxy_redirect off; 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; proxy_set_header Host $http_host; proxy_intercept_errors on; } location /swagger/ { proxy_pass http://mysite:8000/swagger/; proxy_redirect off; 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; proxy_set_header Host $http_host; proxy_intercept_errors on; } }
Django urls.py
urlpatterns = [ url(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui')]
问题分析
控制台的语法错误说明Swagger请求的JS/CSS资源实际返回了HTML内容(大概率是React首页),原因是:
- Swagger的静态资源请求未被正确代理到Django后端,被Nginx路由到了React前端服务;
- Django本身未正确配置Swagger静态资源的访问路径,导致请求返回404后被Nginx转发到React页面。
解决方案
1. 修正Django静态资源路由
Swagger的JS/CSS资源默认由Djangostaticfiles模块管理,需确保资源可被访问:
- 开发环境:在
urls.py末尾添加静态资源服务路由:
from django.conf.urls.static import static from django.conf import settings # ... 已有的urlpatterns if settings.DEBUG: urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
- 生产环境:先执行命令收集静态资源到
STATIC_ROOT目录:
python manage.py collectstatic
然后在Nginx中添加静态资源服务的location:
location /static/ { alias /path/to/your/django/static_root/; # 替换为实际STATIC_ROOT路径 expires 30d; add_header Cache-Control "public, max-age=2592000"; }
2. 调整Swagger资源引用路径(可选)
如果Swagger使用相对路径加载资源(如./swagger-ui-bundle.js),会导致请求路径错误。以drf-yasg为例,修改schema_view配置启用绝对路径:
schema_view = get_schema_view( openapi.Info( title="API Docs", default_version='v1', # 其他配置信息 ), public=True, # 开启后使用绝对路径引用静态资源 permission_classes=[permissions.AllowAny], )
3. 验证Nginx路由匹配
暂时关闭错误拦截,查看静态资源请求的实际状态码:
- 注释Nginx配置中的
proxy_intercept_errors on;,重启Nginx后查看Network面板,确认是否返回404; - 若生产环境下静态资源无法访问,检查
STATIC_ROOT目录的权限,确保Nginx可读取其中文件。
测试验证
修改配置后重启服务:
sudo systemctl restart nginx sudo systemctl restart your-django-service # 替换为你的Django服务名
访问https://mysite.com/swagger/,确认静态资源请求返回200,控制台无语法错误。
内容的提问来源于stack exchange,提问作者sushmee
相关产品推荐
相关产品推荐

