本速查表基於 WebSocket 協議規範及前端實踐場景整理,涵蓋核心對象屬性、方法、事件回調及錯誤處理方案,適用於日常開發查閲。

一、WebSocket 核心對象與初始化

1. 核心對象

WebSocket:瀏覽器內置構造函數,用於創建 WebSocket 連接實例,是所有操作的基礎。

2. 初始化語法

// 基礎語法:ws(非加密)或 wss(加密,類似 HTTPS)
const socket = new WebSocket('ws://example.com'); 
// 加密連接示例(生產環境推薦)
const secureSocket = new WebSocket('wss://example.com');
  • 參數説明:URL 必須以 ws://wss:// 開頭,指向支持 WebSocket 協議的服務器地址。

二、WebSocket 核心屬性

屬性名

類型

説明

readyState

數字

連接狀態碼:

0 - CONNECTING(連接中)

1 - OPEN(連接已打開)

2 - CLOSING(關閉中)

3 - CLOSED(已關閉)

bufferedAmount

數字

已發送但未被服務器確認的字節數,用於判斷髮送緩衝區是否已滿

protocol

字符串

實際使用的子協議(若初始化時指定多個協議,返回服務器選中的協議)

url

字符串

創建連接時使用的 URL(只讀)

三、WebSocket 核心方法

方法名

語法

説明

send()

socket.send(data)

向服務器發送數據,data 支持字符串、Blob、ArrayBuffer 類型;

注意:連接未打開(readyState!==1)時調用會報錯

close()

socket.close(code, reason)

主動關閉連接;

code(可選):關閉狀態碼(默認 1005,代表無狀態碼);

reason(可選):字符串,描述關閉原因

四、WebSocket 核心事件回調

WebSocket 通過“事件驅動”處理連接生命週期,需通過綁定回調函數響應各類狀態變化。

事件名

綁定方式

觸發場景

open

socket.onopen = () => {}

連接成功建立時觸發(readyState 變為 1)

message

socket.onmessage = (event) => {}

收到服務器發送的數據時觸發;

通過 event.data 獲取數據(自動解析為字符串/Blob)

error

socket.onerror = (error) => {}

連接發生錯誤時觸發(如握手失敗、網絡中斷);

注意:錯誤後連接可能自動關閉

close

socket.onclose = (event) => {}

連接關閉時觸發(主動關閉或被動關閉);

通過 event.code 獲取關閉狀態碼,event.reason 獲取關閉原因

五、常見錯誤與解決方案

錯誤類型

可能原因

解決方案

瀏覽器不支持 WebSocket

使用 IE8 及以下等舊瀏覽器

檢測 typeof WebSocket !== 'function',提示用户更換 Chrome/Firefox 等現代瀏覽器

握手失敗(handshake error)

URL 格式錯誤、服務器未支持 WebSocket

1. 檢查 URL 前綴是否為 ws:///wss://

2. 確認服務器已開啓 WebSocket 服務

連接意外關閉(connection closed)

網絡波動、服務器重啓、長時間無數據傳輸

onclose 中添加重連邏輯(排除主動關閉場景),結合心跳機制維持連接

發送數據失敗

連接未打開(readyState!==1)、數據格式錯誤

1. 發送前檢查 readyState

2. 確保數據為字符串/Blob/ArrayBuffer 類型

連接超時(timeout)

網絡延遲高、服務器超時策略

實現 Ping/Pong 心跳機制(每 30s 發送 Ping 幀),避免連接被服務器主動斷開

六、關鍵狀態碼説明

WebSocket 定義了標準化狀態碼,用於標識連接關閉原因,開發中可通過 event.code 獲取:

狀態碼

含義

場景示例

1000

正常關閉

客户端/服務器主動調用 close() 關閉連接

1001

端點離開

客户端頁面關閉、服務器下線

1002

協議錯誤

數據格式不符合 WebSocket 協議規範

1003

不支持的數據類型

發送服務器不支持的數據格式(如二進制數據)

1005

無狀態碼

關閉時未指定狀態碼(默認值)

1006

異常關閉

網絡中斷、連接意外斷開(無明確原因)

七、實戰常用工具函數

1. 連接狀態檢測

// 檢查連接是否可發送數據
function isSocketAvailable(socket) {
  return socket && socket.readyState === WebSocket.OPEN;
}

2. 安全發送數據

// 確保連接打開後再發送數據
function safeSend(socket, data) {
  if (isSocketAvailable(socket)) {
    socket.send(typeof data === 'object' ? JSON.stringify(data) : data);
  } else {
    console.error('WebSocket 連接未打開,發送失敗');
  }
}

3. 心跳機制實現

// 為 socket 添加心跳(每 30s 發送 Ping,5s 未響應則重連)
function addHeartbeat(socket, reconnectFn) {
  let heartbeatTimer;
  let checkTimer;

  // 發送心跳
  function sendPing() {
    if (isSocketAvailable(socket)) {
      socket.send(JSON.stringify({ type: 'ping' }));
      // 等待 Pong 響應
      checkTimer = setTimeout(() => {
        socket.close(1006, '心跳無響應');
        reconnectFn(); // 重連函數
      }, 5000);
    }
  }

  // 啓動心跳
  heartbeatTimer = setInterval(sendPing, 30000);

  // 收到 Pong 時清除檢查計時器
  socket.onmessage = (event) => {
    const data = JSON.parse(event.data);
    if (data.type === 'pong') {
      clearTimeout(checkTimer);
    }
  };

  // 關閉時清除計時器
  socket.onclose = () => {
    clearInterval(heartbeatTimer);
    clearTimeout(checkTimer);
  };
}