webSocket拦截

2,739 阅读1分钟

需求:能不能拿到别人网站的webSocket的数据

实现:通过重写webSocket方法来实现代理拦截

代码

(function(){
    window.hookSocket = function (funs){
      function hookfun(fun) {
        return function () {
          var args = [].slice.call(arguments)
          //1.如果fun拦截函数存在,则先调用拦截函数
          if (funs[fun] && funs[fun].call(this, ...args)) {
            return;
          }
          //2.调用真正的socket方法
          this.socket[fun].apply(this.socket, args);
        }
      }

      function getFactory(attr) {
          return function () {
            return this[attr + "_"] || this.socket[attr]
          }
      }

      function setFactory(attr) {
          return function (f) {
              var socket = this.socket;
              var that = this;
              //区分是否回调属性
              if (attr.indexOf("on") != 0) {
                  this[attr + "_"] = f;
                  return;
              }
              if (funs[attr]) {
                  socket[attr] = function () {
                      funs[attr](...arguments) || f.apply(socket, arguments);
                  }
              } else {
                socket[attr] = f;
              }
          }
      }
      //保存真正的WebSocket对象
      window._ahrealSocket = window._ahrealSocket || WebSocket
      //1.覆盖全局WebSocket,代理对象
      WebSocket = function(url){
        this.socket = new window._ahrealSocket(url);
        for(var attr in this.socket){
          var type = ''
          try {
            type = typeof this.socket[attr]
          } catch (error) { }
        
          if(type == 'function'){
            //2.代理方法
            this[attr] = hookfun(attr)
          }else{
            //3.代理属性
            Object.defineProperty(this, attr, {
              get: getFactory(attr),
              set: setFactory(attr)
            })
          }
        }
      }
    }
  })()
  
  
  //开始拦截
  hookSocket({
    onopen(e){
      console.log('打开webSocket链接')
    },
    onmessage(e){
      console.log(e.data,'这是webSocket返回的数据')
    },
    send(e){
      console.log(e,'这是webSocket发送的数据')
    },
    onclose(e){
      console.log('关闭webSocket')
    }
  })
  
  //注入以上代码到别人的网站后就可以拦截数据拉
  //如:别人网站的socket代码
  var btn1 = document.querySelector('#btn1');
  btn1.onclick = function(){
      var ws = new WebSocket('ws://localhost:3001');
      ws.onopen = function(evt) { 
        ws.send("Hello WebSockets!");
      };
      ws.onmessage = function(evt) {
        console.log( "WebSocket返回的数据: " + evt.data);
      };
      ws.onclose = function(evt) {
        console.log("Connection closed.");
      }; 
  }