Javascript Can';t获取Chrome扩展内容脚本(document_start)以将同步第三方脚本注入<;头>;块

Javascript Can';t获取Chrome扩展内容脚本(document_start)以将同步第三方脚本注入<;头>;块,javascript,google-chrome-extension,content-script,Javascript,Google Chrome Extension,Content Script,我有一个第三方,它利用MutationObserver有条件地转换新添加的节点,出于明显的原因,需要将其包含在块中 如果我手动更新网站的源代码,并将第三方包含在块中,则一切正常,并且第三方能够观察到发生的所有突变 然而,如果我使用Chrome扩展将第三方注入网站的块中,则第三方正被正确地注入网站的块中,但相对而言,观察到的突变很少 我对Chrome>DevTools>网络面板的审查显示,第三方在块内的元素中的请求数量可变后,开始其加载序列。在这一发现之后,我进行了更多的研究——我能够确认Chro

我有一个第三方
,它利用
MutationObserver
有条件地转换新添加的节点,出于明显的原因,需要将其包含在
块中

如果我手动更新网站的源代码,并将第三方
包含在
块中,则一切正常,并且第三方
能够观察到发生的所有突变

然而,如果我使用Chrome扩展将第三方
注入网站的
块中,则第三方
正被正确地注入网站的
块中,但相对而言,观察到的突变很少

我对Chrome>DevTools>网络面板的审查显示,第三方
块内的
元素中的
请求数量可变后,开始其加载序列。在这一发现之后,我进行了更多的研究——我能够确认Chrome确实默认异步加载动态注入的
标记

在下面,您可以找到正在使用的相关
manifest.json
配置,以及我尝试为其注入第三方
的几种不同方法

manifest.json

head.content-script.js(尝试1)

head.content-script.js(尝试3)


还有其他人经历过这个挑战吗?如果有更好的方法,我也愿意接受建议。我甚至愿意使用类似的东西来动态修改响应。同样,我使用Chrome扩展的主要目标是以一个平滑、可靠的页面加载结束——就好像我已经手动更新了网站的源代码,以包含第三方
这里有一个完美的工作解决方案。功劳归于wOxxOm

head.content script.js

var script = document.createElement('script'),
    code = '(' + function() {
        document.write('<script src="//third-party-js.com/third-party.js"><\/scr' + 'ipt>');
    } + ')()';

script.textContent = code;
(document.head || document.documentElement).appendChild(script);
script.remove();
var url='//third-party js.com/third-party.js',
urlEncoded=window.btoa(unescape(encodeURIComponent(url)),
urlContent=localStorage.getItem(urlEncoded);
如果(!urlContent){
var xhr=new XMLHttpRequest();
xhr.open('GET',url,true);
xhr.onload=函数(e){
如果((xhr.readyState==4)和&(xhr.status==200)){
setItem(urlEncoded,xhr.responseText);
window.location.reload(true);
}
};
xhr.send(空);
文件。写(“”);
}否则{
var script=document.createElement('script');
script.textContent=urlContent;
document.documentElement.append(脚本);
}

我猜,Chrome会将非原创的注入内容排队。除了在
标记中注入脚本内容(以前获取并存储在本地),您可能无能为力。但是,如果脚本内容是动态更改的(也就是说,您不能在内容脚本中仅将其作为字符串内联),您必须解决消息/chrome.storage延迟问题,因此您想要的行为将无法得到100%的保证,尝试
document.write
inside trument 4.使用
document.write
in trument#4会在
中插入两个相同的
标记,并且不会创建
块。嗯,尝试在注入的脚本元素中写入:
script.textContent=“document.write(……')”
,appendChild。已报告错误:。您可能需要考虑细节。在Firefox中不起作用“操作不安全”。在POST请求上调用reload也会重新提交表单,这对用户来说是不好的。
document.write('<script async="false" src="//third-party-js.com/third-party.js"></script>');
var script = document.createElement('script');

script.async = false;
script.src = ('//third-party-js.com/third-party.js');

document.documentElement.appendChild(script);
var script = document.createElement('script'),
    code = '(' + function() {
        document.write('<script src="//third-party-js.com/third-party.js"><\/scr' + 'ipt>');
    } + ')()';

script.textContent = code;
(document.head || document.documentElement).appendChild(script);
script.remove();
var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        mutation.addedNodes.forEach(function(addedNode) {
            if (addedNode.nodeName === 'HEAD') {
                var script = document.createElement('script');

                script.async = false;
                script.src = ('//third-party-js.com/third-party.js');

                addedNode.appendChild(script);
            }
        });
    });
});

observer.observe(document, {
    'childList': true,
    'subtree': true
});
var url = '//third-party-js.com/third-party.js',
    urlEncoded = window.btoa(unescape(encodeURIComponent(url))),
    urlContent = localStorage.getItem(urlEncoded);

if (!urlContent) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);

    xhr.onload = function(e) {
        if ((xhr.readyState === 4) && (xhr.status === 200)) {
            localStorage.setItem(urlEncoded, xhr.responseText);
            window.location.reload(true);
        }
    };

    xhr.send(null);

    document.write('<script src="' + url + '"><\/script>');
} else {
    var script = document.createElement('script');
    script.textContent = urlContent;
    document.documentElement.append(script);
}