Execute write on doc: It isn't possible to wri

2019-01-01 13:44发布

问题:

I am trying to load a certain script after page load executes, something like this:

function downloadJSAtOnload(){
            var element = document.createElement(\"script\");
            element.src = \"scriptSrc\";
            document.body.appendChild(element);
        }

         if (window.addEventListener)
                  window.addEventListener(\"load\", downloadJSAtOnload, false);
            else if (window.attachEvent)
                  window.attachEvent(\"onload\", downloadJSAtOnload);
            else window.onload = downloadJSAtOnload;

And while this script seems to execute and download \'scriptSrc\', and append it right before the end of the body tag, it yields the following message (not an error) in the console (chrome)

Failed to execute \'write\' on \'Document\': It isn\'t possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.

What does this even mean? And am I supposed to do something differently? Even though I get the expected behavior?

回答1:

An asynchronously loaded script is likely going to run AFTER the document has been fully parsed and closed. Thus, you can\'t use document.write() from such a script (well technically you can, but it won\'t do what you want).

You will need to replace any document.write() statements in that script with explicit DOM manipulations by creating the DOM elements and then inserting them into a particular parent with .appendChild() or .insertBefore() or setting .innerHTML or some mechanism for direct DOM manipulation like that.

For example, instead of this type of code in an inline script:

<div id=\"container\">
<script>
document.write(\'<span style=\"color:red;\">Hello</span>\');
</script>
</div>

You would use this to replace the inline script above in a dynamically loaded script:

var container = document.getElementById(\"container\");
var content = document.createElement(\"span\");
content.style.color = \"red\";
content.innerHTML = \"Hello\";
container.appendChild(content);

Or, if there was no other content in the container that you needed to just append to, you could simply do this:

var container = document.getElementById(\"container\");
container.innerHTML = \'<span style=\"color:red;\">Hello</span>\';


回答2:

A bit late to the party, but Krux has created a script for this, called Postscribe. We were able to use this to get past this issue.



回答3:

In case this is useful to anyone I had this same issue. I was bringing in a footer into a web page via jQuery. Inside that footer were some Google scripts for ads and retargeting. I had to move those scripts from the footer and place them directly in the page and that eliminated the notice.