How to Add a ≪Script≫ Element to the Dom and Execute Its Code

How to add a <script> element to the DOM and execute its code?

I have no idea how YUI's Node.create() function works, so no comment on that. But a simple cross-browser script is:

  window.onload = function() {
var s = document.createElement('script');
s.type = 'text/javascript';
var code = 'alert("hello world!");';
try {
s.appendChild(document.createTextNode(code));
document.body.appendChild(s);
} catch (e) {
s.text = code;
document.body.appendChild(s);
}
}

The try..catch block is necessary as most browsers like the first method but some don't and throw an error. The second method covers those. You can also simply eval the code, which is more or less equivalent and what some libraries do.

How to insert and execute script tag to the DOM using plain js

You can use insertAdjacentHTML to insert the HTML, then go back and look for the scripts and copy the script src or text, and insert the copy into the DOM to run it:

// Sticking with broadly-supported features:var htmlString = "<div><h1>Title</h1></div><div><script>console.log('it works');<\/script></div>";var target = document.getElementById("target");target.insertAdjacentHTML("beforeend", htmlString);var scripts = target.getElementsByTagName("script");while (scripts.length) {    var script = scripts[0];    script.parentNode.removeChild(script);    var newScript = document.createElement("script");    if (script.src) {        newScript.src = script.src;    } else if (script.textContent) {        newScript.textContent = script.textContent;    } else if (script.innerText) {        newScript.innerText = script.innerText;    }    document.body.appendChild(newScript);}
<div id="target"></div>

Attach script tag code to dom element for execution , alternate for document.write

I was able to resolve it by below code, thought to update if someone in future is stuck on the same problem.

var ad = "whatever encoded here script code";

function decodeHtml(html) {
return $("<textarea/>").html(html).text();
}

function fetch(id, html) {
var elm = document.getElementById(id);
elm.innerHTML = html;
var scripts = elm.getElementsByTagName("script");
var scriptsClone = [];
for (var i = 0; i < scripts.length; i++) {
scriptsClone.push(scripts[i]);
}

for (var i = 0; i < scriptsClone.length; i++) {
var currentScript = scriptsClone[i];
var s = document.createElement("script");
// Copy all the attributes from the original script
for (var j = 0; j < currentScript.attributes.length; j++) {
var a = currentScript.attributes[j];
s.setAttribute(a.name, a.value);
}
s.appendChild(document.createTextNode(currentScript.innerHTML));
currentScript.parentNode.replaceChild(s, currentScript);
}
}

var decoded = decodeHtml(ad);
fetch('YourDivID',decoded);

Add script element to DOM without executing it

Use this to disable Javascript execution in jsdom

jsdom.defaultDocumentFeatures = {
FetchExternalResources: false,
ProcessExternalResources: false
};

If nodejs produces error disable mutation events also in jsdom

jsdom.defaultDocumentFeatures = {
FetchExternalResources: false,
ProcessExternalResources: false,
MutationEvents : false
};

Can scripts be inserted with innerHTML?

You have to use eval() to execute any script code that you've inserted as DOM text.

MooTools will do this for you automatically, and I'm sure jQuery would as well (depending on the version. jQuery version 1.6+ uses eval). This saves a lot of hassle of parsing out <script> tags and escaping your content, as well as a bunch of other "gotchas".

Generally if you're going to eval() it yourself, you want to create/send the script code without any HTML markup such as <script>, as these will not eval() properly.

Inject and execute JavaScript into an existing DOM

script tags added via innerHTML and related methods (insertAdjacentHTML, etc.) are not executed. (The exact rules are somewhere in the script portion of the HTML specification but it's heavy going.) This may be because early on it was identified that poorly-written pages might use innerHTML and such to append user content, and so not executing it was a quick and simple way to avoid very, very basic XSS attacks. But only very, very basic ones.

You can add a script tag to the DOM and have it executed by creating and appending a script tag:

const script = document.createElement("script");
script.textContent = `console.log("Hi there");`;
document.body.appendChild(script);

You can do that from the console tab in devtools, for instance, rather than the DOM inspector tab.

Executing a <script> tag on append after the DOM has loaded

On a whim I made this change:

// document.getElementById('scriptMe').appendChild(s);
document.body.appendChild(s);

and boom, script runs and video loads.

Which is super interesting, because "why", right?

Edit:
In addition, trying other script injection methods discussed here.

document.write method

document.write(s.outerHTML) // s is a script node

also works. In fact, you can embed that script node in a div and it works as well.

createContextualFragment method

// var $container = document.getElementById('scriptMe'); // does not work
var $container = document.body
var range = document.createRange()
$container.appendChild(range.createContextualFragment(script_str))

works, where script_str is an html string literal. This will work both as "<script>....</script>" or "<div id="myDiv"><script>...</script></div>"

but all the methods I tested ultimately needed injection to be done in body.

codepen



Related Topics



Leave a reply



Submit