Django Channels使用AllowedHostsOriginValidator时WebSocket连接被拒绝问题
核心原因
Django Channels的AllowedHostsOriginValidator校验的是WebSocket请求的Origin请求头中的域名/IP部分,不是客户端的访问IP,你如果把自己本地的客户端IP加到了ALLOWED_HOSTS里,本身就不符合校验规则,自然会被拒绝。
正确配置步骤
- 先获取你发起WebSocket请求的页面的Origin值
你可以在浏览器控制台的网络tab里找到对应的WebSocket握手请求,查看请求头中的Origin字段,格式一般是http://xxx:端口或者https://xxx:端口,只需要取xxx的部分(不需要端口、不需要http/https前缀)。 - 将上面拿到的
xxx值加到settings.py的ALLOWED_HOSTS中
举个例子:如果你的Origin是http://192.168.3.2:3000,那就在ALLOWED_HOSTS里加192.168.3.2即可;如果Origin是http://localhost:5173,就加localhost。 - 反向代理场景额外配置
如果你用了Nginx等反向代理,需要在Nginx配置中添加如下规则,把Host头正确传递给后端服务,否则Django拿到的Host值不正确也会校验失败:
proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
跨域场景推荐方案
如果你的前端和后端端口不同属于跨域场景,更推荐用OriginValidator直接指定完整的允许Origin列表,校验逻辑更清晰可控:
# asgi.py 修改配置 from channels.security.websocket import OriginValidator application = ProtocolTypeRouter({ "http": get_asgi_application(), 'websocket': OriginValidator( URLRouter(uppicdoapp.routing.websocket_urlpatterns), # 这里填完整的允许Origin值,包含协议和端口 allowed_origins=[ "http://localhost:3000", "http://192.168.3.2:3000", "https://你的正式域名.com" ] ) })
内容的提问来源于stack exchange,提问作者Karan V
相关产品推荐
相关产品推荐

