添加Caddy实现HTTPS后,Django ASGI应用WebSocket通信异常求助
问题解决步骤
1. 修复WebSocket协议不匹配问题
HTTPS页面中不允许发起未加密的ws://请求(浏览器混合内容限制),这会直接导致WebSocket初始化失败,进而后续调用ws.send()时出现变量未初始化的错误。修改前端代码:
// 自动匹配页面协议,兼容HTTP/HTTPS场景 const protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://'; const ws = new WebSocket(protocol + window.location.host + '/ws/validation/');
如果确定仅在HTTPS环境运行,也可以直接写死协议:
const ws = new WebSocket('wss://' + window.location.host + '/ws/validation/');
2. 确保变量初始化顺序正确
错误can't access lexical declaration 'ws' before initialization说明你在ws变量用let声明完成前就调用了ws.send()。检查代码逻辑:
- 确保WebSocket初始化代码在触发
ws.send()的按钮点击事件绑定之前执行 - 避免在变量声明前的代码块中调用
ws,比如不要在let ws = ...之前的click事件回调里使用ws
3. 验证Caddy的WebSocket转发配置
你的Caddyfile已经添加了WebSocket握手必需的Connection和Upgrade头转发,但需要确认以下细节:
- 访问应用时使用的端口是
8443(对应Caddy映射的443端口),确保WebSocket地址中的端口与页面访问端口一致 - 可以查看Caddy日志,确认带有
Upgrade: websocket的请求是否正常转发到mywebapp:8080
4. Django配置补充检查
- 确认
ALLOWED_HOSTS包含example.com,否则Django会拒绝来自该域名的请求:ALLOWED_HOSTS = ['example.com', 'localhost'] - 检查Channels的
CHANNEL_LAYERS配置,确保Redis连接正常(之前运行正常大概率无问题,HTTPS后若有配置变动需确认):CHANNEL_LAYERS = { 'default': { 'BACKEND': 'channels_redis.core.RedisChannelLayer', 'CONFIG': { "hosts": [('redis', 6379)], }, }, } - 当前
SECURE_PROXY_SSL_HEADER配置('HTTP_X_FORWARDED_PROTO', 'https')正确,可确保Django识别Caddy转发的HTTPS请求
测试验证
- 修改前端代码后,清除浏览器缓存重新加载页面
- 打开浏览器开发者工具的
Console和Network标签,查看WebSocket连接是否成功建立(Network中筛选WS类型) - 若连接失败,查看
Console中的具体错误,比如是否存在自签名证书未手动信任的问题
内容的提问来源于stack exchange,提问作者user279611
相关产品推荐
相关产品推荐

