控制 DOM 中的每个“src”属性更改

Posted

技术标签:

【中文标题】控制 DOM 中的每个“src”属性更改【英文标题】:Getting control of every 'src' attribute change in DOM 【发布时间】:2020-12-21 13:50:07 【问题描述】:

我正在编写一个 javascript 代码,它需要监视新的“脚本”元素,并阻止一些已知来源。

为了捕捉这些,我尝试使用 MutationObserver 和 __ defineSetter __ , 两者都可以观察 'src' 的变化,但只有在 HTTP 请求已经被发送之后 - 所以即使我改变了 src,它并没有真正被阻止。

window.htmlScriptElement.prototype.__defineSetter__('src', function (d) 
    
        console.log("HTMLScriptElement: ",d);
        if (d.indexOf('localhost') != -1) 
            //BLOCK SCRIPT
        
    );

    new MutationObserver(function (a) 
        a.forEach((e) => 
            e.addedNodes.forEach((z) => 
            
                if (z.nodeName.toLowerCase() == "script" && z.src.indexOf('localhost') != -1) 
                
                    //BLOCK SCRIPT
                
            )
        )
    ).observe(window.document, 
        attributes: true,
        childList:true,
        subtree:true
    );

【问题讨论】:

单独使用 MutationObserver 就足够了,但您需要 1) 删除元素,而不仅仅是更改其 src,然后根据需要创建一个新元素,以及 2) 检查嵌套节点,因为 addedNodes 未展平所以一些网站可能会添加一个包含脚本的容器元素。 【参考方案1】:

您可以使用Service workers 来拦截网络请求。像这样的东西应该可以解决问题:

self.addEventListener('fetch', function (event) 
    const blockedUrls = [
        //...
    ];
    if (blockedUrls.some(x => event.request.url.startsWith(x))) 
        event.respondWith(new Response('blocked',  status: 401, statusText: 'Unauthorized' ));
    
);

【讨论】:

你必须把它写在一个单独的文件中(专用于服务工作者)并用navigator.serviceWorker.register('./sw-test/sw.js')注册它。欲了解更多信息:developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/… 我无法使用 Service Worker,因为我的代码在我以外的其他网站上运行。如果我理解正确,我需要安装它 - 所以我无法使用它 那么它确实行不通,因为服务工作者脚本的来源必须与当前来源相同 谢谢,还有其他想法吗? 不幸的是我没有其他想法,我实际上怀疑这是可能的。

以上是关于控制 DOM 中的每个“src”属性更改的主要内容,如果未能解决你的问题,请参考以下文章

attr控制checked属性失效

javascript DOM document属性

使用设置属性 (DOM) 更改操作值

html5如何更改video的src属性

使用 jQuery 更改和加载 iframe ‘src’ 属性

DOM对象控制HTML无素——详解2