本文介绍如何通过 chrome 浏览器扩展,无侵入式地劫持页面已创建的 websocket 实例,实时捕获并 console.log 其发送与接收的数据,适用于调试、安全审计或协议分析场景。
本文介绍如何通过 chrome 浏览器扩展,无侵入式地劫持页面已创建的 websocket 实例,实时捕获并 console.log 其发送与接收的数据,适用于调试、安全审计或协议分析场景。
要实现对网页中已有 WebSocket 连接的收发数据监听(而非新建连接),关键在于在目标页面上下文中重写 WebSocket 原型方法,而非仅替换构造函数。你当前的 content_script.js 存在两个核心问题:
- socket.addEventListener("send", ...) 是无效的——WebSocket 原生不触发 "send" 事件;
- 仅重写 window.WebSocket 构造函数,无法拦截已在页面加载后创建的实例(如你的 websocket.js 中提前初始化的 socket)。
✅ 正确方案是:在 content script 中直接 monkey-patch WebSocket.prototype.send 和 WebSocket.prototype.addEventListener(针对 message),确保所有 WebSocket 实例(无论何时创建)均被统一拦截。
以下是优化后的 content_script.js(推荐部署方式):
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
// content_script.js —— 必须注入到页面主帧(main world),非 isolated world
(function () {
// 确保在页面全局上下文执行(避免沙箱隔离)
if (typeof window === 'undefined') return;
const originalSend = WebSocket.prototype.send;
const originalAddEventListener = WebSocket.prototype.addEventListener;
WebSocket.prototype.send = function (data) {
console.log('[WebSocket → Sent]', {
url: this.url,
data: typeof data === 'string' ? data : (data instanceof Blob ? '(Blob)' : '(Binary)'),
timestamp: new Date().toISOString()
});
return originalSend.apply(this, arguments);
};
// 拦截 message 事件(需覆盖 addEventListener 以捕获注册行为)
WebSocket.prototype.addEventListener = function (type, listener, options) {
if (type === 'message') {
const wrappedListener = function (event) {
console.log('[WebSocket ← Received]', {
url: this.url,
data: event.data,
timestamp: new Date().toISOString()
});
listener.call(this, event);
}.bind(this);
return originalAddEventListener.call(this, type, wrappedListener, options);
}
return originalAddEventListener.call(this, type, listener, options);
};
})();
? 重要注意事项:
- ✅ 注入时机:content_scripts 必须设置 "run_at": "document_start"(默认为 document_idle),确保在页面脚本执行前完成原型劫持;
- ✅ 匹配范围:"matches" 应覆盖目标站点(如 "https://*/*"),且 "all_frames": true 可捕获 iframe 内 WebSocket;
- ⚠️ 不要使用 chrome.scripting.executeScript 动态注入:background.js 中监听网络请求再注入的方式不可靠,且 details.tabId 在 onRuleMatchedDebug 中不可用;应直接通过 manifest 声明式注入;
- ⚠️ 避免污染全局作用域:使用 IIFE 包裹代码,防止变量泄漏;
- ? 调试技巧:可在 DevTools Console 中手动测试 WebSocket.prototype.send.toString(),确认是否已被重写。
? 进阶建议:
若需结构化日志或 UI 展示,可结合 chrome.runtime.sendMessage 将日志转发至 popup 页面;对于二进制数据(ArrayBuffer/TypedArray),建议添加 JSON.stringify(new Uint8Array(data)) 或 Base64 编码处理。
通过此方案,你无需修改原网站代码,即可稳定、全面地监控任意 WebSocket 连接的通信内容——真正实现“旁路监听”。










