Execute Write on Doc: It Isn't Possible to Write into a Document from an Asynchronously-Loaded External Script Unless It Is Explicitly Opened

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

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>';

Nuxt + External script - Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external

Solution 1 - If you need the script globally.

Simply use vue-meta (already included into Nuxt) as you would do with other scripts. Add it to layouts/default.vue:

<template>
...
</template>

<script>
export default {
...

head () {
return {
script: [
{
hid: 'any-label-for-the-script',
src: 'SCRIPT_URL'
// async: true,
// defer: true
}
]
}
},

...

// If you need to run SOME_FUNCTION from downloaded script
mounted () {
// eslint-disable-next-line no-undef
SOME_FUNCTION(param1, param2, ...)
}
}
</script>

Solution 2 - If you need script just on some route/component.

  1. Install postscribe: npm install --save postscribe

  2. Create plugins/postscribe.client.js file with content:

import postscribe from 'postscribe'

export default (context, inject) => {
inject('postscribe', (elementId, scriptCode) => {
postscribe(elementId, scriptCode)
})
}

  1. Inside nuxt.config.js add just created file:
export default {
...
plugins: [
...

{ src: '~/plugins/postscribe.client.js' }

...
],
...
}

  1. In your component do this:
<template>
<div id="add-script-here" />
</template>

<script>
...

mounted () {
// eslint-disable-next-line no-useless-escape
this.$postscribe('#add-script-here', '<script src="SCRIPT_URL"><\/script>')

// If you need to do something onload, then instead of the line above do it like this:
// this.$postscribe('#add-script-here', '<script onload="DO_SOMETHING_ONLOAD_HEAR" src="SCRIPT_URL"><\/script>')
}

...
</script>

Usually script should be added to head or body, but it seems that postscribe can not do this, so lets use add-script-here.

Error: It isn't possible to write into a document from an asynchronously-loaded external script

This library might solve your problem https://github.com/krux/postscribe

Asynchronously write javascript, even with document.write.

<div id="ad"><h5>Advertisement</h5></div>

<script type="text/javascript">
// jQuery used as an example of delaying until load.
$(function() {
// Build url params and make the ad call
postscribe('#ad', '<script src=doubleclick_url_with_params><\/script>');
});
</script>

Warning: A call to document.write() from an asynchronously-loaded external script was ignored. How is this fixed?

Don't use document.write. The script is being loaded asynchronously, which means it's detached from the document parsing state. There is quite literally NO WAY for the JS engine to know WHERE the document.write should be executed in the page.

The external script could load instantaneously and the document.write executes where the <script src="..."> tag is, or it could hit a net.burp and load an hour later, which means the document.write gets tagged at the end of the page. It's quite literally a race condition, so JS engines will ignore document.writes from scripts loaded asynchronously.

Convert the document.write to use regular DOM operations, guarded by a document.onload type handler.

svelte : embedded github gist throws Failed to execute 'write' on 'Document'

You can work around this by rendering the Gist in an <iframe>:

<!-- Gist.svelte -->
<script>
export let gistUrl = ""

import { onMount } from 'svelte'

let frame;
onMount(() => {
frame.srcdoc = `<script src='${gistUrl}.js'><${""}/script>`;
});
</script>
<style>
iframe {
border: 0;
width: 100%;
height: 100%;
}
</style>
<iframe src="about:blank" bind:this={frame} title="Gist"></iframe>

Try it in the REPL

Google maps async load: It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened

A:
It's possible that your url string just has a typo.
Lets say you played with args and ended up with

url = https://maps.googleapis.com/maps/api/js?v=3.exp?callback=callback

google maps won't recognize the callback option and fetch the sync js script that uses a call to document.write(), instead of loading the correct async version.
You can check for yourself, if after load you have a maps.googleapis.com script maps/api/js?v=3.. and it contains a getScriptcall containing document.write(), you've ended up in the wrong (sync) version..



Related Topics



Leave a reply



Submit