Javascript中的WebSocket如何工作?

WebSocket通过HTTP升级握手建立持久全双工连接:客户端发含Upgrade、Sec-WebSocket-Key的请求,服务器返回101状态及Sec-WebSocket-Accept校验;连接后通过onopen/onmessage/onclose/onerror事件收发数据,以帧而非HTTP报文传输,支持文本、二进制、Ping/Pong;需用wss://加密,服务器需校验Origin,原生无自动重连。

WebSocket 在 JavaScript 中通过一次 HTTP 握手建立持久、全双工的 TCP 连接,之后客户端和服务器可随时互发数据,无需重复请求。

握手阶段:用 HTTP 升级协议

浏览器发起一个带特殊头的 HTTP 请求:

  • Upgrade: websocketConnection: Upgrade 表明想切换协议
  • Sec-WebSocket-Key 是客户端生成的随机 Base64 字符串,用于防伪造
  • 服务器验证后,返回 HTTP 101 Switching Protocols 状态码
  • 响应头含 Sec-WebSocket-Accept —— 由客户端密钥经固定算法计算得出,供客户端校验

握手成功,连接就脱离 HTTP,进入 WebSocket 帧通信模式。

连接建立后:监听事件收发消息

JS 使用 WebSocket 构造函数创建实例,并绑定关键事件:

  • onopen:连接就绪,可立即调用 socket.send() 发送首条消息
  • onmessage:收到数据时触发,event.data 是字符串或 ArrayBuffer
  • onclose:连接关闭(可能是主动断开或网络中断),event.codeevent.reason 可辅助诊断
  • onerror:发生不可恢复错误(如 URL 无效、跨域被拒、TLS 握手失败)时触发

数据传输:帧结构与双向自由通信

所有数据都封装成 WebSocket 帧传输,不是 HTTP 报文:

  • 文本消息自动按 UTF-8 编码,二进制数据需用 ArrayBufferBlob
  • 支持 Ping/Pong 控制帧 维持连接活跃,防止中间代理超时断连
  • 客户端和服务器地位对等,都能主动发消息,不依赖“请求-响应”流程
  • 连接期间无请求开销,延迟低、带宽省,适合高频小数据(如聊天、行情、协作编辑)

连接管理:安全、跨域与稳定性

实际使用中需注意几个关键点:

  • wss:// 对应 HTTPS,强制加密;ws:// 仅限开发或内网环境
  • WebSocket 不受浏览器同源策略限制,但服务器必须显式允许来源(如检查 Origin 头)
  • 原生 API 不自带重连,需手动实现:监听 onclose 后延时重建 new WebSocket(url)
  • 发送前建议检查 socket.readyState === WebSocket.OPEN,避免报错

基本上就这些。