0

是否有任何方法(实施或仅在理论上)可以检测到第三方站点上分配的 JavaScript 事件和操作?

如果我将 JavaScript 注入到外部站点并希望避免覆盖onsubmit,onclickonfocus其他此类事件,有没有办法检测和扩展此类回调而不是覆盖它们?

我有过的想法:

  • 事先在无头浏览器或 JavaScript 引擎中运行网站以捕获所有已执行的 JavaScript
  • 即时解析 JavaScript 并希望第三方 JavaScript 符合我的解析器的期望
4

2 回答 2

4

如果您只想添加新的事件处理程序而不覆盖现有的事件处理程序,您可以使用addEventListener()or attachEvent()(对于旧版本的 IE)而不是设置.onclick,.onsubmit等来添加新的事件处理程序而不影响以前的事件处理程序。

这是一个添加事件的简单跨浏览器功能:

// add event cross browser
function addEvent(elem, event, fn) {
    if (elem.addEventListener) {
        elem.addEventListener(event, fn, false);
    } else {
        elem.attachEvent("on" + event, function() {
            // set the this pointer same as addEventListener when fn is called
            return(fn.call(elem, window.event));   
        });
    }
}

我知道从常规 javascript 中没有跨浏览器的方式来询问现有的 DOM 对象以查看哪些具有通过addEventListener或安装的常规 javascript 事件处理程序attachEvent。如果事件处理程序是用 jQuery 安装的,则可以通过这种技术来询问它们。

未来的规范工作已经完成,以添加一个列出所有事件处理程序的属性,但我不确定它是否已实现。您可以在此处阅读更多相关信息。

对于使用onclickonsubmitonfocus等安装的事件处理程序,您可以检查所有现有的 DOM 元素以查看哪些已为这些事件分配了处理程序,然后您可以根据需要挂钩它们。

// add other events here you are interested in
var events = ["onclick", "onsubmit", "onfocus", "onblur"];
var elems = document.getElementsByTagName("*"), item;
for (var i = 0; i < elems.length; i++) {
    item = elems[i];
    for (var j = 0; j < events.length; j++) {
        if (item[events[j]]) {
            console.log("event handler for " + events[j]);
        }
    }
}
于 2012-10-02T01:07:40.677 回答
1

addEventListener你实际上可以通过改变and的原型得到你想要的attachEvent

// intercept events cross browser
var method;
if (HTMLElement.prototype.addEventListener) {
  method = 'addEventListener';
} else {
  method = 'attachEvent';
}
HTMLElement.prototype.realAddEventListener = HTMLElement.prototype[method];
HTMLElement.prototype[method] = function(a,b,c) {
  console.log('here are all the events being added:', arguments);
  this.realAddEventListener(a,b,c);
};

当然,在任何其他页面脚本之前将其添加到页面中很重要,但它可以在 jQuery 之类的库之后或之前添加,但可能会在原型上与prototype.js 发生冲突,不确定。

您还需要检查onclicks整个事件集,您可以通过console.dir(document.createElement('a'))在 javascript 控制台中运行来找到这些事件。

于 2012-10-02T05:13:43.423 回答