【问题标题】:Add middleware to an event将中间件添加到事件
【发布时间】:2020-05-20 03:17:30
【问题描述】:

我一直在尝试对事件处理程序进行修改,以便在它通常被发送到真正的事件处理程序函数之前拦截它。

例子:

var ws =  new WebSocket("/ws.ws");
ws.onmessage = function(event){
    console.log("A normal event received")
}
// or using ws.addeventlistener("message",function(){})

现在,在我执行上面的代码之前,我将执行我的中间件来拦截未来将创建的每个 websocket 对象上的 onmessage 事件的所有事件调用。然后中间件将对事件对象进行修改,然后将其转发给真实事件。

我知道如何使用 WebSocket.send 方法做到这一点。

var proxySend = WebSocket.prototype.send;
WebSocket.prototype.send = function() {
    console.log("Intercepted a send call",arguments)
    //make a change to the arguments here
    return proxySend.apply([].slice(arguments));
}

但我不知道如何处理消息事件。我相信这是不可能的,但值得一试。我在 chrome 扩展中使用它,所以中间件总是会在网页加载之前加载。

更新:

如果网站使用 addeventlistener 函数通过使用我在 WebSocket.send 示例中展示的相同技巧来添加事件,我可以做到这一点。

因为 ws.onmessage 现在是我卡在的地方。

我尝试通过对 onmessage 原型使用​​ getter/setter 来执行建议的操作。

var eventRef = null;
Object.defineProperty(WebSocket.prototype, 'onmessage', {
  get: function() { return eventRef ; },    
  set: function(onmessageEventHandler){ 
    eventRef = function(event){
      console.log("Before onMessage event"); // my middleware
      onmessageEventHandler(event);
    }
  }
});

但它不会控制台记录“onMessage 事件之前”,甚至不会调用分配给 onmessage 事件的函数。

如果您想对其进行测试,可以在这里尝试。为了便于测试,我将其修改为 onclick。 https://codepen.io/MyPenAccount/pen/MWaZrwE

【问题讨论】:

  • 您可以尝试将 getter/setter 添加到现有原型。无需有人设置onmessage 属性,而是使用内部管道调用您的函数。
  • 默认情况下,ws.onmessage=null,所以你可以添加任何你想要的。
  • @Evert 我想到了。问题是您无法访问 onmessage 原型。尝试访问 WebSocket.prototype.onmessage 时会出现非法调用错误。
  • @waiaan 我这样做的目的是将该中间件加载到我不拥有的网站上。我无权访问 ws,因为它会在其他人的代码中。如果有办法在调用 new Websocket() 时获取 ws 对象,我可能会找到一种方法
  • @JohnSmith 那么如何让您的代码在您不拥有的网站上运行?

标签: javascript middleware


【解决方案1】:

我不知道这是否能完全解决您的问题,但您可以这样做:

Object.defineProperty(HTMLElement.prototype, "onclick", {   
    set: function(handler) { 
        // Maybe clear previous installed click handlers
        // or prevent multiple calls to this.

        this.addEventListener("click", function(event) {
            alert("Middleware")

            handler(event)
        })
    }
})

【讨论】:

  • 我对代码做了一些小改动以修复多次重新分配codepen.io/MyPenAccount/pen/QWjzaqM 它似乎确实做了我想要它做的事情。我睡眠不足,所以我可能错了,但这正是它应该做的。
  • @JohnSmith 是的,这有点像我使用 setter/getter =)的意思=)
猜你喜欢
  • 1970-01-01
  • 2012-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-09
  • 1970-01-01
相关资源
最近更新 更多