Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run script after appending it to the HTML

I have a string with HTML:

var str = '<div><p>Examplee</p></div><script>alert("testing!")</script>';

and then I append it to the HTML:

document.body.innerHTML += str;

and the content is appended but the script does not execute, is there a way to force it?

like image 960
nick Avatar asked Sep 29 '25 09:09

nick


1 Answers

First, a caveat: Naturally, only do this with scripts you trust. :-)

There are a couple of ways. Basically, you need to:

  1. Get the text of the script, and

  2. Run it

Getting the text

One option is just to go ahead and add it, then find it and grab its text:

document.body.innerHTML += str;
var scripts = document.querySelectorAll("script");
var text = scripts[scripts.length - 1].textContent;

On obsolete browsers, you may need to feature-detect textContent vs. innerText.

You might want to give it an identifying characteristic (id, class, etc.) so you don't have to find it by position like that.

Alternately, you could do what the PrototypeJS lib does and try go get it from the string with regex. You can find their source code for doing that here (look for extractScripts).

Running it

Once you have the text of the script, you have several options:

  • Use indirect eval (aka "global eval") on it: (0, eval)(text). This is not the same as eval(text); it runs the code in global scope, not local scope.

  • Create a new script element, set its text to the text, and add it

    var newScript = document.createElement("script");
    newScript.textContent = text;
    document.body.appendChild(newScript);
    

    If doing that, might make sense to remove the original, though it doesn't really matter.

Example that grabs the text of the script element after adding it and uses indirect eval:

var str = '<div><p>Examplee</p></div><script>alert("testing!")<\/script>';
document.body.innerHTML += str;
var scripts = document.querySelectorAll("script");
(0, eval)(scripts[scripts.length - 1].textContent);

Presumably you don't really use += on document.body.innerHTML, which builds an HTML string for the whole page, appends to it, tears the whole page down, and then parses the new HTML to build a new one. I assume that was just an example in your question.

like image 153
T.J. Crowder Avatar answered Oct 02 '25 04:10

T.J. Crowder



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!