我一直在尝试对事件处理程序进行修改,以使其拦截,然后再将其发送到真实的事件处理程序功能。
示例:
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扩展程序中使用了此功能,因此始终会在加载网页之前加载中间件。
更新:
如果网站使用我在WebSocket.send示例中显示的相同技巧,使用addeventlistener函数添加事件,则可以这样做。
因为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);
}
}
});
但是它没有console.log“ onMessage事件之前”,甚至没有调用分配给onmessage事件的函数。
如果您想测试它,可以在这里尝试。我将其修改为onclick以便于测试。 https://codepen.io/MyPenAccount/pen/MWaZrwE
答案 0 :(得分:0)
我不知道这是否可以完全解决您的问题,但是您可以:
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)
})
}
})