如何解决Django+Nginx环境下的WebSocket连接失败问题?
Django + Nginx 环境下WebSocket连接失败的排查与解决
一、先确认Django/ASGI服务的WebSocket可用性
如果用Channels实现WebSocket,先确保ASGI服务本身能正常处理连接:
- 启动ASGI服务(以Daphne为例):
daphne your_project.asgi:application --bind 0.0.0.0 --port 8000 - 直接在服务器本地用工具测试:
wscat -c ws://127.0.0.1:8000/ws/your_path,如果能连通,说明Django端没问题,问题出在Nginx代理或前端配置。
二、Nginx必须添加WebSocket升级规则
这是核心配置,Nginx默认不会处理WebSocket的Upgrade请求,需要在对应location块中添加以下规则:
location /ws/ { # 转发到ASGI服务的地址和端口 proxy_pass http://127.0.0.1:8000; # 启用HTTP/1.1,WebSocket依赖此版本 proxy_http_version 1.1; # 传递WebSocket升级头 proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # 传递必要的主机和客户端信息 proxy_set_header Host $host; 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_read_timeout 86400; }
- 替换
/ws/为你的WebSocket路由前缀,http://127.0.0.1:8000为ASGI服务的实际监听地址。 - 如果是HTTPS环境(443端口),前端连接要用
wss://协议,Nginx的SSL配置需正常,上述location块放在server的443配置段内即可。
三、修正前端连接URL
生产环境下不需要直接连接8000端口,Nginx会帮你转发:
- 错误写法:
new WebSocket('ws://your_domain:8000/ws/your_path') - 正确写法(自动适配HTTP/HTTPS):
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; const socket = new WebSocket(`${protocol}//${window.location.host}/ws/your_path`);
四、端口与防火墙检查
- 8000端口仅需在服务器内部开放给Nginx,不需要对外暴露,防火墙无需放行8000(除非要直接测试ASGI服务)。
- 必须确保80/443端口对外放行,且Nginx正在监听这两个端口:执行
netstat -tulpn | grep -E '80|443|8000'确认监听状态。
五、日志排查
- 查看Nginx错误日志:
tail -f /var/log/nginx/error.log,检查是否有代理失败、头信息错误等提示。 - 查看ASGI服务日志,确认WebSocket请求是否到达后端。
- 浏览器控制台查看具体错误,比如跨域问题(若前后端域名不同,需在Nginx或Django中配置CORS规则)。
内容的提问来源于stack exchange,提问作者Gabriel Dalacorte
相关产品推荐
相关产品推荐

