要拦截消息,您必须监视 onmessage = fn 和 addEventListener("message", fn) 调用。
为了能够修改onmessage,我们必须首先覆盖全局WebSocket。下面是拦截传入的消息,但您可以通过类似的方式窥探send 方法来拦截传出消息(客户端发送到服务器的消息)。
我在使用 Firebase 的页面上对此进行了测试,它运行良好,但您必须在其他脚本之前对其进行初始化,以确保 websocket 库(可以是 socket.io、ws 等)正在使用覆盖的 @987654326 @构造函数。
监视传入消息和修改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() {
// Here you can get the actual data from the incoming messages
// Here you can even change the data before calling the real message listener
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) {
// Only intercept
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)
// Eventually change the sent data
// arguments[0] = ...
// arguments[1] = ...
return originalSend.apply(this, arguments)
}
ws.send = proxiedSend
return ws;
};
window.WebSocket = ProxiedWebSocket;
如果有任何不清楚的地方,请随时提出任何问题。