WebSocket 握手是一个标准的HTTP GET请求,必须包含以下关键头字段:Upgrade: websocket(表明希望升级协议)、Connection: Upgrade(表明连接将被升级)、Sec-WebSocket-Key(由客户端生成的16字节随机值,经Base64编码后发送,用于防止缓存代理误响应)、Sec-WebSocket-Version: 13(当前唯一广泛支持的协议版本)。此外,Host头是HTTP/1.1的必需字段,Origin头由浏览器自动添加(用于服务端判断跨域合法性)。
如果服务端支持WebSocket 协议并同意升级,必须返回状态码101 Switching Protocols,且响应头中必须包含:Upgrade: websocket、Connection: Upgrade、Sec-WebSocket-Accept(由客户端Sec-WebSocket-Key与固定GUID字符串"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"拼接后计算SHA-1哈希,再经Base64编码得出)。服务端不得在响应中包含Sec-WebSocket-Key或重复Sec-WebSocket-Version。如果握手失败,服务端应返回4xx或5xx状态码。
握手失败通常源于以下原因:客户端发送了除GET外的HTTP方法、请求URI不符合WebSocket URL格式(必须以ws://或wss://开头)、缺少必需头字段或字段值格式错误(如Sec-WebSocket-Key非合法Base64或解码后非16字节)、服务端返回的Sec-WebSocket-Accept计算错误、响应中缺失任一必需头。在企业网络环境中,反向代理或防火墙未正确透传Upgrade和Connection头也会导致握手失败。