Загрузка скриптов с помощью document.write в скрипте содержимого расширения

Если скрипт содержит:

document.write("<iframe>ads here</iframe>");

Если он включен в html до того, как страница будет запрошена для загрузки, это может выглядеть примерно так:

<html>
<!-- stuff !-->
<div><script src="document_write.js" type="text/javascript"></script></div>
<body>
</html>

Загрузка html-страницы с кодом, подобным приведенному выше, приведет к тому, что <iframe> будет помещен в тег <div>, в котором размещен скрипт. Если document.write() вызывается после загрузки страницы, она перезапишет всю страницу.

Скрипты содержимого расширений Chrome также перезаписывают страницу с помощью document.write или приводят к ее сбою — в зависимости от того, когда в жизненном цикле страницы она была вызвана.

Есть ли способ вставить сценарии, содержащие document.write(), в сценарии содержимого Chrome?


person dsp_099    schedule 12.11.2013    source источник
comment
Есть ли особая причина, по которой вы используете document.write() в сценарии содержимого?   -  person Qantas 94 Heavy    schedule 12.11.2013
comment
Я бы предпочел этого не делать, но это очень распространено для сторонних скриптов, таких как реклама и трекеры.   -  person dsp_099    schedule 12.11.2013
comment
Пробовали ли вы использовать атрибут content_scripts runt_at?   -  person gkalpak    schedule 12.11.2013
comment
У меня есть; время, когда JS, который я хочу вставить, на самом деле не решает проблему. Я не могу запустить document.write со сценарием до того, как HTML даже загрузится — даже если это произойдет, это определенно не то место, куда я хочу поместить полученный код ‹iframe› или что-то в этом роде.   -  person dsp_099    schedule 12.11.2013
comment
Извините, не совсем понятно, в чем проблема и чего вы пытаетесь достичь. (Вероятно, это связано с тем, что мне повезло с рекламой, трекерами и т. д.)   -  person gkalpak    schedule 13.11.2013
comment
Есть ли у вас доступ для изменения тех сценариев, которые содержат вызовы document.write() (или вам нужно использовать их как есть)?   -  person gkalpak    schedule 18.11.2013


Ответы (1)


Я столкнулся с той же проблемой, когда работал с некоторыми сценариями отслеживания конверсий на своем сайте ajax. В итоге я переопределил document.write, что решило проблему.

$(document).ready(function() {
    document.write = function(str) {
        var moz = !window.opera && !/Apple/.test(navigator.vendor);
        if (str.match(/^<\//))
            return;
        if (!window.opera)
            str = str.replace(/&(?![#a-z0-9]+;)/g, "&amp;");
        str = str.replace(/<([a-z]+)(.*[^\/])>$/, "<$1$2></$1>");
        if (!moz)
            str = str.replace(/(<[a-z]+)/g, "$1 xmlns='http://www.w3.org/1999/xhtml'");
        var div = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
        div.innerHTML = str;
        var pos;
        if (!moz) {
            pos = document.getElementsByTagName("*");
            pos = pos[pos.length - 1];
        } else {
            pos = document;
            while (pos.lastChild && pos.lastChild.nodeType == 1)
                pos = pos.lastChild;
        }
        var nodes = div.childNodes;
        while (nodes.length)
            pos.parentNode.appendChild(nodes[0]);
    };
});
person Shreyas    schedule 18.11.2013
comment
Можете пояснить цель тестирования для оперы и сафари? - person dsp_099; 18.11.2013
comment
Это общее переопределение, которое я получил из блога Джона Резига [ejohn.org/ блог/xhtml-documentwrite-and-adsense/] - person Shreyas; 18.11.2013
comment
Я понимаю. В блоге говорится, что это решение не работает для IE — верно ли оно для более новой версии IE9+? - person dsp_099; 18.11.2013