拦截消息,需要监听
onmessage = fn
和
addEventListener("message", fn)
的调用。
要能修改
onmessage
,我们首先必须覆盖全局的
WebSocket
。下面的代码可以拦截传入的消息,类似的方式也可以监控
send
方法以拦截客户端发送到服务器的消息。
我已经在使用 Firebase 的网页上测试过并且有效,但你需要在其他脚本之前初始化它,并确保 WebSocket 库(例如 socket.io、ws 等)正在使用被覆盖的
WebSocket
构造函数。
间谍传入的消息并修改
data
:
最终你可以在调用真正的消息监听器之前
覆盖数据data
- 如果您无法控制页面功能并希望在消息监听器中注入自己的数据,则这将非常有用。
const OriginalWebsocket = window.WebSocket
const ProxiedWebSocket = function() {
console.log("Intercepting web socket creation")
const ws = new OriginalWebsocket(...arguments)
const originalAddEventListener = ws.addEventListener
const proxiedAddEventListener = function() {
if (arguments[0] === "message") {
const cb = arguments[1]
arguments[1] = function() {
Object.defineProperty(e, "data", { value: 'your injected data' })
console.log("intercepted", arguments[0].data)
return cb.apply(this, arguments)
}
}
return originalAddEventListener.apply(this, arguments)
}
ws.addEventListener = proxiedAddEventListener
Object.defineProperty(ws, "onmessage", {
set(func) {
return proxiedAddEventListener.apply(this, [
"message",
func,
false
]);
}
});
return ws;
};
window.WebSocket = ProxiedWebSocket;
如果您不需要修改数据,可以按照答案的第二部分操作。
窃听传入消息而不修改数据
如果您只想监听消息而不覆盖数据,事情就更简单了:
const OriginalWebsocket = window.WebSocket
const ProxiedWebSocket = function() {
const ws = new OriginalWebsocket(...arguments)
ws.addEventListener("message", function (e) {
console.log(e.data)
})
return ws;
};
window.WebSocket = ProxiedWebSocket;
监听发送的消息
你可以通过代理用于向服务器发送数据的send
方法,以非常类似的方式来监听它。
const OriginalWebsocket = window.WebSocket
const ProxiedWebSocket = function() {
const ws = new OriginalWebsocket(...arguments)
const originalSend = ws.send
const proxiedSend = function() {
console.log("Intercepted outgoing ws message", arguments)
return originalSend.apply(this, arguments)
}
ws.send = proxiedSend
return ws;
};
window.WebSocket = ProxiedWebSocket;
如果有任何不清楚的地方,请随时提出问题。