Django Channels 2.0中用self.code(1007)拒连时websocketbridge.js报403错误
解决Django Channels 2.0聊天室连接拒绝时客户端403错误的问题
我之前也踩过这个坑,你遇到的问题核心在于WebSocket握手阶段的处理逻辑和Channels默认行为不匹配:
当你在connect方法里还没调用self.accept()就直接用self.close(code=1007)拒绝连接时,Channels会返回HTTP 403状态码终止WebSocket握手——这是HTTP层面的拒绝,而非WebSocket连接建立后的关闭帧。但你用的websocketbridge.js会把这种握手失败判定为异常,所以抛出了Error during WebSocket handshake: Unexpected response code: 403。
最直接的解决方案:先接受连接,再发送关闭帧
正确的做法是先完成WebSocket握手,再立即发送关闭帧告知客户端房间不存在。这样客户端会收到标准的WebSocket关闭事件,而非握手错误。
后端代码修改示例:
from channels.generic.websocket import WebSocketConsumer from asgiref.sync import async_to_sync class ChatConsumer(WebSocketConsumer): def connect(self): # 从URL路由中提取房间名称 self.room_name = self.scope['url_route']['kwargs']['room_name'] # 先完成WebSocket握手 self.accept() # 检查房间是否存在(替换成你的实际检查逻辑) if not self._check_room_exists(): # 发送1007关闭帧,告知客户端房间不存在 self.close(code=1007) return # 房间存在时,执行后续加入房间的逻辑 self.room_group_name = f'chat_{self.room_name}' async_to_sync(self.channel_layer.group_add)( self.room_group_name, self.channel_name ) def _check_room_exists(self): # 示例:这里写你判断房间是否存在的业务逻辑 # 比如从数据库查询对应房间记录 return False # 测试时返回False模拟房间不存在
前端代码处理关闭事件:
修改前端代码,监听WebSocket的close事件,根据关闭码处理房间不存在的情况:
const bridge = new WebSocketBridge(); bridge.connect('/ws/discuss/asdf/asdf1'); // 监听WebSocket关闭事件 bridge.socket.addEventListener('close', (event) => { if (event.code === 1007) { alert('该房间不存在,请检查房间名称!'); // 这里可以添加更多用户友好的提示逻辑 } }); // 可选:监听错误事件处理其他异常情况 bridge.socket.addEventListener('error', (error) => { console.error('WebSocket连接出错:', error); });
为什么不推荐直接在握手阶段拒绝?
WebSocket规范中,握手阶段的拒绝是通过HTTP状态码返回的,而关闭帧是连接建立后才会发送的信号。websocketbridge.js作为Channels官方前端库,对握手失败的处理就是抛出异常,这是符合规范的行为。所以先握手再关闭是更标准的做法,也能避免客户端抛出不必要的异常。
内容的提问来源于stack exchange,提问作者Nav
相关产品推荐
相关产品推荐

