Skip to content

参考:API 速查 / 对比 / 易错点

基于 WHATWG WebSockets 现行标准与各浏览器 Baseline 状态 · 核于 2026-07

速查

  • 构造new WebSocket(url[, protocols])——即连接,返回 CONNECTING 态;urlws / wss / http / https(2024 起)/ 相对 URL,带 fragment 或非法 scheme 抛 SyntaxError
  • protocols:字符串或数组,最终只选中一个;握手后读只读属性 protocol;数组重复 / 非法格式抛 SyntaxError
  • 不能自定义握手头Authorization / Sec-* 都设不了——鉴权路线见网络章
  • readyState 四态CONNECTING(0) / OPEN(1) / CLOSING(2) / CLOSED(3),只读、单向流动、实例不可复用。
  • send 五类型string(文本帧)+ ArrayBuffer / Blob / TypedArray / DataView(二进制帧);CONNECTING 调用抛 InvalidStateErrorCLOSING / CLOSED 静默丢弃,缓冲满自动断连。
  • close 约束code 只能 100030004999,其余抛 InvalidAccessErrorreason UTF-8 ≤ 123 字节否则 SyntaxError;不丢已排队消息、对已关连接是空操作。
  • 四事件openEvent)/ messageMessageEvent)/ errorEvent无细节)/ closeCloseEvent)。
  • MessageEventdatastring 或二进制,取决于 binaryType)/ origin / lastEventId(WS 恒空)。
  • CloseEvent 三件code / reason / wasClean1006=异常无 Close 帧、1005=无状态码、1015=TLS 失败,这三个只能读不能用 close()
  • error 无信息 + 必跟 close:诊断看 CloseEventcode / wasClean,重连逻辑挂 onclose
  • binaryType:唯一可写属性,"blob"(默认)/ "arraybuffer";只影响接收;默认值与 RTCDataChannel 相反。
  • bufferedAmount:发送侧唯一背压信号,已排队未发出的字节数、发完归 0; bufferedamountlow 事件(那是 RTCDataChannel 的),节流靠轮询。
  • 接收无背压:标准 WebSocket 的能力短板,靠 Worker / 采样 / 服务端限速缓解。
  • 生命周期:不 close 就泄漏且挡 bfcache;离场 pagehide 关、pageshowpersisted 重建;切勿 unload
  • WebSocketStream 前沿:Chrome 124+、非标准、仅 Chromiumopened{ readable, writable, extensions, protocol }closed{ closeCode, reason }close({ closeCode, reason }),构造支持 signal
  • 边界:握手 / 帧 / 心跳 / 重连策略 / 关闭码运维语义 / 代理 LB / 鉴权 / 子协议协商机制 / wss / HTTP2 上的 WS 全在网络章

一、WebSocket 接口速查

构造与属性

成员读写说明
new WebSocket(url[, protocols])构造即连接;url 支持 ws/wss/http/https/相对;非法 URL / fragment / scheme 抛 SyntaxError
url只读解析后的绝对 URL
protocol只读服务端选中的子协议(未选为空串)
extensions只读服务端选中的扩展(通常空串)
readyState只读0 CONNECTING / 1 OPEN / 2 CLOSING / 3 CLOSED
bufferedAmount只读send 未发出的字节数;发完归 0
binaryType读写"blob"(默认)/ "arraybuffer",仅影响接收

方法

方法说明异常
send(data)排队发送,异步;五类型(见下)CONNECTING 态抛 InvalidStateErrorCLOSING/CLOSED 静默丢弃
close([code[, reason]])发起关闭握手,不丢已排队消息,幂等code1000/30004999InvalidAccessErrorreason UTF-8 > 123 字节抛 SyntaxError

send 数据类型

类型备注
string文本帧UTF-8 编码
ArrayBuffer二进制帧原始字节
TypedArrayUint8Array 等)二进制帧视图字节
DataView二进制帧视图字节
Blob二进制帧Blob.type 被忽略

二、事件与 CloseEvent

四个事件

事件事件对象触发时机关键点
openEvent握手成功、进入 OPEN之后才能 send
messageMessageEvent收到一条消息无命名事件,全进这里
errorEvent连接出错无任何细节(安全设计),后必跟 close
closeCloseEvent连接关闭诊断信息在此

MessageEvent 属性

属性说明
datastring(文本帧)或 Blob / ArrayBuffer(二进制帧,取决于 binaryType
origin消息来源的源
lastEventIdWebSocket 场景恒为空串

CloseEvent 属性

属性说明
code关闭码(含只读的 1005/1006/1015
reason服务端给的原因文本(UTF-8,可能空)
wasClean是否走完关闭握手;false 常伴 1006

三、合法关闭码(API 约束视角)

关键区分:你能主动传给 close(code),与你能在 CloseEvent.code 里读到的,是两个不同的集合。

码 / 范围close() 能传?CloseEvent 能读到?说明
0999✗ 抛 InvalidAccessError未使用
1000正常关闭(close() 不传参的默认)
10011015(除保留)✗ 抛 InvalidAccessError协议 / 浏览器产生,JS 不能主动传
1005✓(合成)无状态码;只读
1006✓(合成)异常断开、无 Close 帧;只读,重连判据
1015✓(合成)TLS 握手失败;只读
30003999库 / 框架 / 应用(IANA 注册)
40004999私有约定

上表只讲 API 层「哪些码合法、谁产生」。各码的运维语义1001 端点离开、1011 服务端错误、1013 过载退避……分别意味着什么、该怎么处置)见网络章MDN CloseEvent.code

四、binaryType 对比

WebSocket.binaryTypeRTCDataChannel.binaryType
默认值"blob""arraybuffer"
可选值"blob" / "arraybuffer""blob" / "arraybuffer"
影响仅接收的二进制帧类型同左
迁移坑两者默认相反——跨 API 复用 onmessage 逻辑必显式设

选择建议:要同步随机读字节DataView / WASM / 二进制协议解析)→ "arraybuffer"大文件 / 整体转手createObjectURL、下载)→ "blob"

五、与 SSE / WebTransport 的 API 视角选型

维度WebSocketSSE(EventSourceWebTransport
方向全双工双向服务器 → 客户端单向双向
API 形态事件驱动(onmessage + send事件驱动(onmessage,只收)Streams + datagrams(Promise / 流)
数据类型文本 + 二进制仅文本(UTF-8)文本 + 二进制
自动重连(自己写)内建(自带 Last-Event-ID
背压接收无、发送靠轮询 bufferedAmount无(只收,量通常小)Streams 天然背压
底层TCP(HTTP/1.1 Upgrade,或 RFC 8441 走 H2)HTTP 长响应HTTP/3 over QUIC(多路复用、无队头阻塞)
消息边界有(一帧一消息)有(空行分隔)流无固定边界 / datagram 有
标准化现行标准、全绿现行标准、全绿较新,浏览器支持推进中
API 侧一句话双向、二进制、自管重连单向、纯文本、省心自带重连双向 + 背压 + 不可靠 datagram,面向新场景

选型速断(API 能力视角,协议 / 性能取舍见网络章):

  • 只要服务器单向推文本(通知、日志、进度、行情)→ SSE,省一大堆重连代码。
  • 要双向、要二进制、要低延迟互推WebSocket
  • 要双向 + 背压 + 可选不可靠 datagram(音视频 / 游戏状态)且能接受较新支持面WebTransport(了解为主)。

六、易错点清单

  • new 完立刻 send:此刻 readyStateCONNECTING,抛 InvalidStateError——必须等 open
  • CLOSING / CLOSEDsend静默丢弃、不报错,消息神秘消失的头号嫌疑。
  • close(1001) / close(500):只能传 100030004999,其余抛 InvalidAccessError;协议保留码你读得到、传不了。
  • reason 超 123 字节:按 UTF-8 字节算(中文每字 3 字节),超了抛 SyntaxError
  • 指望 error 事件给原因:它没有任何细节(安全设计);诊断看随后 closecode / wasClean
  • 以为断线会自动重连:WebSocket 不自动重连(这点和 SSE 相反),得自己写(骨架见生命周期页)。
  • 复用作废实例重连CLOSED 的实例不能 reopen,重连必须 new 新的。
  • 等一个「命名事件」:WebSocket 没有 SSE 的 event: 概念,所有消息进同一个 message——消息类型自己在 payload 里带。
  • 二进制默认当 ArrayBuffer:默认 binaryType"blob"e.dataBlob 不是 ArrayBuffer;要字节先设 "arraybuffer"await blob.arrayBuffer()
  • 从 RTCDataChannel 搬代码忘了默认相反WebSocket 默认 "blob"RTCDataChannel 默认 "arraybuffer"instanceof 判断会走错分支。
  • 狂发不看 bufferedAmount:缓冲膨胀、内存涨,满了浏览器自动断连;大流量必须节流(轮询 bufferedAmount)。
  • bufferedamountlow 事件:标准 WebSocket 没有这事件(那是 RTCDataChannel 的);发送背压只能轮询。
  • 接收侧想施加背压:标准 API 做不到,只能 Worker / 采样 / 让服务端限速,或了解 WebSocketStream
  • 文本体积用 .length:那是字符数不是字节数;按 UTF-8 字节用 new TextEncoder().encode(s).length
  • 忘了 close():连接常驻后台(幽灵连接)、还挡 bfcache;SPA 组件卸载 / 离开页面必关。
  • unload / beforeunload 收尾:会破坏 bfcache;离场一律 pagehide,恢复用 pageshowpersisted
  • HTTPS 页发 ws://:被混合内容拦截、连接失败(不是构造异常);生产一律 wss
  • WebSocketStream 当生产 API非标准、仅 Chromium,Firefox / Safari 无;用前特性检测 + 降级。
  • 想在浏览器设握手头Authorization / Sec-* 都设不了;鉴权走 Cookie / ticket / 子协议夹带(见网络章)。

七、权威链接