WebSocket握手是遵循HTTP/1.1规范的GET请求,客户端须发送Upgrade、Connection、Sec-WebSocket-Key、Sec-WebSocket-Version和Host头,服务端响应101状态码并返回对应Upgrade、Connection和Sec-WebSocket-Accept头,计算需严格符合RFC 6455。

WebSocket 握手本质上是一次特殊的 HTTP GET 请求,由客户端发起,服务端响应 101 Switching Protocols。虽然它最终升级为 WebSocket 协议,但握手阶段完全遵循 HTTP/1.1 规范(RFC 7230、RFC 7231),且受 RFC 6455(WebSocket Protocol)对头字段的明确定义约束。
客户端必须发送的关键请求头
浏览器或客户端实现需严格包含以下头字段:
- Upgrade: websocket — 表明客户端希望升级协议,值必须小写且精确匹配,不能是 "WebSocket" 或 "WEBSOCKET"
- Connection: Upgrade — 表明连接将被升级,不是保持持久连接
-
Sec-WebSocket-Key — 由客户端生成的 Base64 编码随机 16 字节值(如
dGhlIHNhbXBsZSBub25jZQ==),不可预测、不可复用,用于防止缓存代理误响应 -
Sec-WebSocket-Version: 13 — 当前唯一标准版本;若服务端不支持该版本,应返回 426 并在
Sec-WebSocket-Version响应头中列出支持的版本 - Host — 符合 HTTP/1.1 要求,必须存在且与目标服务器一致
服务端必须校验并返回的响应头
服务端接受升级时,响应状态码必须为 101 Switching Protocols,且必须包含:
- Upgrade: websocket — 值必须小写,与请求一致
- Connection: Upgrade — 明确指示协议切换完成
-
Sec-WebSocket-Accept — 由客户端
Sec-WebSocket-Key与固定字符串"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"拼接后计算 SHA-1,再 Base64 编码得出(例如 keydGhlIHNhbXBsZSBub25jZQ==→ accepts3pPLMBiTxaQ9kYGzzhZRbK+xOo=)
服务端不得在响应中包含 Sec-WebSocket-Key 或重复 Sec-WebSocket-Version;若拒绝握手,应返回 4xx/5xx 状态码,并可选返回 Sec-WebSocket-Version(拒绝版本不匹配时)或 Sec-WebSocket-Extensions(协商失败时)。
立即学习“前端免费学习笔记(深入)”;
可选但受规范约束的头字段
以下头字段允许出现,但行为受 RFC 6455 严格限定:
-
Sec-WebSocket-Protocol — 客户端可发送逗号分隔的子协议列表(如
chat, superchat);服务端若支持,必须在响应中回传**恰好一个**已选协议(不能多传、不能改名、不能新增) -
Sec-WebSocket-Extensions — 用于协商扩展(如
permessage-deflate);客户端发送请求参数,服务端若接受,须原样回传所选扩展及参数(不允许添加未请求的扩展) - Origin — 浏览器自动添加(非 CORS 场景下),用于服务端判断跨域合法性;非浏览器客户端可不发,但服务端不应依赖其存在做安全决策
禁止或需特别注意的行为
违反以下任一要求即视为握手失败,服务端应返回 400 或直接关闭连接:
- 客户端发送除
GET外的任意 HTTP 方法 - 请求 URI 不符合 WebSocket URL 格式(
ws://或wss://开头,路径和查询参数合法) - 缺少必需头字段,或字段值格式错误(如
Sec-WebSocket-Key非合法 Base64、长度非 24 字符) - 服务端返回的
Sec-WebSocket-Accept计算错误,或响应中缺失任一必需头 - 在握手响应中携带 HTTP 消息体(101 响应必须无 body)
所有头字段名不区分大小写,但推荐使用首字母大写的规范格式(如 Sec-WebSocket-Key);字段值中的空格、换行、多余分隔符均违反 HTTP/1.1 语法,会导致解析失败。











