我正在尝试对Safari进行扩展,使用户可以使用新的API在每个站点上阻止javascript。该API可让您注入一个javascript文件,该文件将在任何内容之前加载到网站上,其功能不如常规javascript,就好像它在HTML页面上运行一样。有没有一种方法可以使用javascript阻止所有javascript?
API含糊地告诉我,“注入的脚本是在网页完全加载之前执行的,因此可以在将资源添加到网页时采取措施。”我是否可以挂入一些事件来捕获正在加载的资源并阻止它们?
答案 0 :(得分:2)
有一种方法可以阻止 most Javascript:在页面加载的最开始处附加一个MutationObserver,并且只要文档发生更改,如果找到<script>
标签,请将其删除:>
<script>
new MutationObserver(() => {
console.log('Mutation observer running...');
document.body.querySelectorAll('script').forEach(scr => scr.remove());
})
.observe(document.documentElement, { childList: true, subtree: true });
</script>
<script>
console.log('hi');
</script>
内联处理程序中的Javascript仍然可以运行,但是幸运的是,与<script>
标记(由于这是一种不好的做法),和相比,内联Java并不是那么普遍无论如何,实质性Javascript都将放在<script>
标记中,因此内联Javascript可能可能由于引用未定义的函数而经常引发错误。
尽管subtree: true
在动态添加元素时比其他MutationObserver昂贵得多,但由于(几乎可以肯定)页面上没有运行Javascript,这应该不是问题,尤其是在页面完全加载后
要同时删除内联处理程序,请检查添加的元素是否具有on
属性,并删除它们:
<script>
const cleanNode = (node) => {
if (node.nodeType !== 1) {
// Not an element node:
return;
}
if (node.matches('script')) {
node.remove();
}
[...node.attributes].forEach((attr) => {
if (attr.name.startsWith('on')) {
node.removeAttribute(attr.name);
}
});
};
new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
[...mutation.addedNodes].forEach(cleanNode);
});
})
.observe(document.documentElement, { childList: true, subtree: true });
</script>
<script>
console.log('hi');
</script>
<img onerror="alert('JS running')" src>