截取文档静态节点上每个内联事件的注册

问题描述 投票:0回答:2

使用JavaScript,我希望在它们被触发之前拦截我的文档中每个内联事件处理程序的注册。对于文档的静态节点(即,不是由脚本动态注入的节点),我想删除内联事件处理程序并将它们转换为外部事件处理程序(外部处理程序意味着直接从JavaScript调用node.AddEventListener函数)。但是对于动态节点,我想保留内联事件处理程序(动态节点是使用JavaScript注入的节点)。

例如:

<body>
<img onerror="alert(1)" />
<script>
document.getElementById("a").innerHTML = "<img onerror='alert(2)'/>";
</script>
<div id="a"></div>
</body>

在上面的示例中,我希望将alert(1)错误事件转换为外部事件,同时将alert(2)错误事件保留为内联。我知道如何将内联事件处理程序转换为外部,但我不知道如何1)在“注册”时和实际触发之前拦截内联处理程序。 2)区分静态节点和动态节点的处理程序。

我知道这是一个难题,但任何帮助/评论都会很棒:)

javascript browser dom-events
2个回答
0
投票

在您的其他内联事件处理程序被触发或注册之前,您可以查看两个有用的DOM事件。你应该注意window.onloadDOMContentLoaded事件。

所有页面内容(包括所有资源(CSS,JS,图像等))都会触发onload事件。另一方面,DOMContentLoaded在文档完成加载(DOM已准备好)但不依赖其依赖资源时被触发。含义HTML标记,文本和样式已准备就绪。

为此,jQuery有一个跨浏览器的.ready()事件。

$(document).ready(function() {
    // do something when the DOM is ready.
});

你可以在onerror事件之前打断。如果你想通过javascript(和jQuery)轻松地使用它们,你应该为你的元素分配ID或类:<img id="img1" onerror="alert(1)" />。所以,假设您想要摆脱使用onerror事件触发的警报;你可以做到这一点,例如:

$(document).ready(function() {
    $('#img1').unbind('error');
    //OR $('img').first().unbind('error'); 
            //to get the first image element from your actual code
});

这将删除error元素上img1事件的(unbounds)处理程序。如果要从所有图像中删除错误事件处理程序,可以执行以下操作:

$('img').unbind('error');

如果要删除旧的并将新错误事件分配给特定元素:

$('#img1').unbind('error').error(function(event){
    // do stuff...
});

回答你的第二个问题;你无法真正区分静态和动态添加的事件处理程序。但是,只需将代码放在添加动态处理程序的行之前。

希望这可以帮助。


0
投票

我不知道如何拦截内联事件的注册,但是可以拦截内联脚本的执行。

虽然浏览器不提供控制内联事件的接口,但内联事件也是遵守W3C规范的DOM事件。要理解以下实现,您最好在HTML DOM API中了解事件传播:Bubbling and capturing, two ways of event propagation

根据上面的文章,在所有浏览器中(IE <9除外),有两个阶段的事件处理。事件首先下降 - 这称为捕获,然后冒泡。此行为在W3C规范中是标准化的。因此,我们可以通过将事件绑定到父节点来拦截捕获阶段中的节点的内联事件。例如:

<img src="" onerror="alert('Yahoo!');" id="target" />
<script>
    document.addEventListener('error', function(e) {
        var element = e.target;
        if (element.id == "target") {
            e.stopImmediatePropagation();
            console.log("The alert is intercepted.");
        }
    }, true);
</script>

我们绑定到上面的文档的事件将在img.onerror之前执行,而e.stopImmediatePropagation()会阻止当前事件的进一步传播。因此,没有机会触发内联的错误事件。

参考:http://fex.baidu.com/blog/2014/06/xss-frontend-firewall-1/

© www.soinside.com 2019 - 2024. All rights reserved.