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.
Install postscribe:
npm install --save postscribe
Create
plugins/postscribe.client.js
file with content:
import postscribe from 'postscribe'
export default (context, inject) => {
inject('postscribe', (elementId, scriptCode) => {
postscribe(elementId, scriptCode)
})
}
- Inside
nuxt.config.js
add just created file:
export default {
...
plugins: [
...
{ src: '~/plugins/postscribe.client.js' }
...
],
...
}
- 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 getScript
call containing document.write()
, you've ended up in the wrong (sync) version..
Related Topics
Is There a Max Number of Arguments JavaScript Functions Can Accept
What Are the Common Defenses Against Xss
Asynchronous Exception Handling with Bluebird Promises
Document.Getelementbyid VS Jquery $()
How to Get a Utc Timestamp in JavaScript
Current Time Formatting with JavaScript
How to Read 'Native Code' JavaScript Functions
Create an Array with Same Element Repeated Multiple Times
How Does Sort Function Work in JavaScript, Along with Compare Function
How to Get Get and Post Variables with Jquery
How to Find If an Array Contains a Specific String in JavaScript/Jquery
Wait 5 Seconds Before Executing Next Line
Queryselector, Wildcard Element Match
Cross-Platform, Cross-Browser Way to Play Sound from JavaScript
How to Capitalize the First Letter of Each Word in a String Using JavaScript
HTML Button to Not Submit Form
Addeventlistener with Ajax Not Working Well
How to Show Just the First Line of Text of a Div and Expand on Click