JavaScript WebSocket class

JavaScript WebSocket class

我需要记录 WebSocket 流量,所以我准备编写一个 Chrome 扩展,它会注入一些 JavaScript 代码,应该可以解决问题。

WebSocket = new Proxy(WebSocket, {
  construct: (target, args) => {
    console.log('new WebSocket instance');
    return new target(...args);
  }
})

我需要重写什么方法来记录发送和接收的消息?

如何修改此类消息 sent/received?一个简单的工作代码将不胜感激。

我将构造并 return 一个普通的 WebSocket,并根据需要附加您自己的自定义方法,而不是代理:

const origWebSocket = window.WebSocket;
window.WebSocket = function(url) {
  const socket = new origWebSocket(url);
  socket.send = (msg) => {
    console.log('intercepted send:', msg);
    origWebSocket.prototype.send.call(socket, msg);
  };
  socket.addEventListener('message', (event) => {
    console.log('intercepted receive:', event.data);
  });
  return socket;
};

// patching done
const socket = new WebSocket('wss://echo.websocket.org');
socket.onopen = () => {
  socket.send('hi');
};

要同时修改传入消息,您可以修补实例的 onmessage 属性(如果需要,还可以修补 addEventListener 属性),这样,收到消息时,它会在用户回调运行之前首先通过您的自定义函数:

const origWebSocket = window.WebSocket;
const origOnMessage = Object.getOwnPropertyDescriptor(WebSocket.prototype, 'onmessage').set;
window.WebSocket = function(url) {
  const socket = new origWebSocket(url);
  Object.defineProperty(socket, 'onmessage', {
    set(cb) {
      origOnMessage.call(socket, (e) => {
        // Have to use defineProperty because `data` is a getter on the prototype
        Object.defineProperty(e, 'data', { value: e.data + ' modified' });
        cb(e);
      });
    }
  });
  socket.send = (msg) => {
    console.log('intercepted send:', msg);
    origWebSocket.prototype.send.call(socket, msg);
  };
  socket.addEventListener('message', (event) => {
    console.log('intercepted receive:', event.data);
    event.data = 'foobar';
  });
  return socket;
};

// patching done
const socket = new WebSocket('wss://echo.websocket.org');
socket.onopen = () => {
  socket.send('hi');
};
socket.onmessage = e => console.log('consumer sees message:', e.data);