将中间件添加到事件
Add middleware to an event
我一直在尝试对事件处理程序进行修改,以便在它通常被发送到真正的事件处理函数之前拦截它。
示例:
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);
}
}
});
但它不会 console.log "Before onMessage event",甚至不会调用分配给 onmessage 事件的函数。
如果你想测试它,你可以在这里试试。为了便于测试,我将其修改为 onclick。 https://codepen.io/MyPenAccount/pen/MWaZrwE
我不知道这是否能完全解决您的问题,但您可以这样做:
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)
})
}
})
我一直在尝试对事件处理程序进行修改,以便在它通常被发送到真正的事件处理函数之前拦截它。
示例:
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);
}
}
});
但它不会 console.log "Before onMessage event",甚至不会调用分配给 onmessage 事件的函数。
如果你想测试它,你可以在这里试试。为了便于测试,我将其修改为 onclick。 https://codepen.io/MyPenAccount/pen/MWaZrwE
我不知道这是否能完全解决您的问题,但您可以这样做:
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)
})
}
})