Wykonywanie elementów <script> wstawionych z .innerHTML

112

Mam skrypt, który wstawia zawartość do elementu za pomocą innerHTML.

Może to być na przykład:

<script type="text/javascript">alert('test');</script>
<strong>test</strong>

Problem polega na tym, że kod wewnątrz <script>tagu nie jest wykonywany. Trochę googlowałem, ale nie było żadnych widocznych rozwiązań. Jeśli wstawiłem zawartość za pomocą jQuery, $(element).append(content);części skryptu otrzymałyby evalprzed wstrzyknięciem do DOM.

Czy ktoś ma fragment kodu, który wykonuje wszystkie <script>elementy? Kod jQuery był nieco skomplikowany, więc nie mogłem zrozumieć, jak to zostało zrobione.

Edycja :

Zaglądając do kodu jQuery udało mi się dowiedzieć, jak jQuery to robi, co zaowocowało następującym kodem:

Demo:
<div id="element"></div>

<script type="text/javascript">
  function insertAndExecute(id, text)
  {
    domelement = document.getElementById(id);
    domelement.innerHTML = text;
    var scripts = [];

    ret = domelement.childNodes;
    for ( var i = 0; ret[i]; i++ ) {
      if ( scripts && nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
            scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
        }
    }

    for(script in scripts)
    {
      evalScript(scripts[script]);
    }
  }
  function nodeName( elem, name ) {
    return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
  }
  function evalScript( elem ) {
    data = ( elem.text || elem.textContent || elem.innerHTML || "" );

    var head = document.getElementsByTagName("head")[0] || document.documentElement,
    script = document.createElement("script");
    script.type = "text/javascript";
    script.appendChild( document.createTextNode( data ) );
    head.insertBefore( script, head.firstChild );
    head.removeChild( script );

    if ( elem.parentNode ) {
        elem.parentNode.removeChild( elem );
    }
  }

  insertAndExecute("element", "<scri"+"pt type='text/javascript'>document.write('This text should appear as well.')</scr"+"ipt><strong>this text should also be inserted.</strong>");
</script>
phidah
źródło
1
Dlaczego nie możesz po prostu iterować elementów potomnych elementu i dla każdego elementu skryptu po prostu eval () wewnętrzny kod HTML tego dziecka? Tak właśnie widziałem, jak robi to duży dostawca komponentów, za każdym razem, gdy wykonują wywołanie zwrotne Ajax, które dodaje coś do DOM, robią dokładnie to. Pamiętaj jednak, że może to być powolne, szczególnie w IE7.
slugster
2
Andreas: Jeśli dodam funkcję, na przykład function testFunction(){ alert('test'); }do kodu wstawionego do innerHTML, a następnie spróbuję ją wywołać, oznacza to, że funkcja nie jest zdefiniowana.
phidah,
1
Niesamowita phidah, działa jak urok, pozdrawiam
Marcin
3
Myślę, że absolutnie ważne jest, aby zrozumieć, że jest to zamierzone zachowanie przeglądarki w celu zapobiegania atakom typu Cross-site scripting. Jeśli tekst, który ustawiłeś jako innerHTML, jest dostarczony przez Boba, zostanie on wykonany w przeglądarce Alicji, powodując uszkodzenia (pomyśl o forum, na którym ludzie mogą pisać komentarze, dodając do nich tagi skryptów). Możesz przeczytać więcej na ten temat tutaj: en.wikipedia.org/wiki/Cross-site_scripting . Zachowaj bezpieczeństwo!
Xatian
1
HTML bardzo się zmienił od 2010 roku. W dzisiejszych czasach może chcesz wyglądać: stackoverflow.com/a/58862506/890357
marciowb

Odpowiedzi:

27

Skrypt programu operacyjnego nie działa w IE 7. Z pomocą SO, oto skrypt, który robi:

exec_body_scripts: function(body_el) {
  // Finds and executes scripts in a newly added element's body.
  // Needed since innerHTML does not run scripts.
  //
  // Argument body_el is an element in the dom.

  function nodeName(elem, name) {
    return elem.nodeName && elem.nodeName.toUpperCase() ===
              name.toUpperCase();
  };

  function evalScript(elem) {
    var data = (elem.text || elem.textContent || elem.innerHTML || "" ),
        head = document.getElementsByTagName("head")[0] ||
                  document.documentElement,
        script = document.createElement("script");

    script.type = "text/javascript";
    try {
      // doesn't work on ie...
      script.appendChild(document.createTextNode(data));      
    } catch(e) {
      // IE has funky script nodes
      script.text = data;
    }

    head.insertBefore(script, head.firstChild);
    head.removeChild(script);
  };

  // main section of function
  var scripts = [],
      script,
      children_nodes = body_el.childNodes,
      child,
      i;

  for (i = 0; children_nodes[i]; i++) {
    child = children_nodes[i];
    if (nodeName(child, "script" ) &&
      (!child.type || child.type.toLowerCase() === "text/javascript")) {
          scripts.push(child);
      }
  }

  for (i = 0; scripts[i]; i++) {
    script = scripts[i];
    if (script.parentNode) {script.parentNode.removeChild(script);}
    evalScript(scripts[i]);
  }
};
Larry K.
źródło
4
Lepiej użyj jQuery $(parent).html(code)- zobacz moją odpowiedź poniżej.
Iirekm
po wstrzyknięciu skryptu do DOM, jak mam go usunąć?
S4beR
1
Skrypt nie jest rekurencyjny, więc będzie patrzył tylko na bezpośrednie dzieci. To działa dla mnie:if (nodeName(child, "script" ) && (!child.type || child.type.toLowerCase() === "text/javascript")) { scripts.push(child); } else { exec_body_scripts(child); }
st4wik
2
Zwróć uwagę, że powyższy kod nie wykonuje skryptów ładowanych przez src. Powyższy skrypt można zmienić, aby sprawdzał elem.srci warunkowo ustawiał srcwłaściwość utworzonego elementu skryptu zamiast ustawiania jego zawartości tekstowej.
Ryan Morlok
Dlaczego nie skorzystać z globalnej evalsztuczki zamiast tworzyć <script>element i wstawiać go do pliku <head>? Obaj wykonują kod JS bez ujawniania bieżącego zamknięcia.
Finezja
31

@phidah ... Oto bardzo interesujące rozwiązanie Twojego problemu: http://24ways.org/2005/have-your-dom-and-script-it-too

Więc zamiast tego wyglądałoby to tak:

<img src="empty.gif" onload="alert('test');this.parentNode.removeChild(this);" />

user447963
źródło
2
a nawet lepiej, nie ma potrzeby mieć obrazka ze zdarzeniem "onerror", fajny do szybkiego wtrysku XSS jvfconsulting.com/blog/47/… :)
baptx
11
Możesz użyć, <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" onload="alert('test');">jeśli chcesz zapobiec bezużytecznemu żądaniu http.
Savas Vedova
1
kocham to ! (dodano style="display:none;) aby ukryć ikonę zepsutego obrazu
kris
Właściwie <style>jest lepszy niż <img>, ponieważ nie
basen
24

Oto krótszy, wydajniejszy skrypt, który działa również w przypadku skryptów z tą srcwłaściwością:

function insertAndExecute(id, text) {
    document.getElementById(id).innerHTML = text;
    var scripts = Array.prototype.slice.call(document.getElementById(id).getElementsByTagName("script"));
    for (var i = 0; i < scripts.length; i++) {
        if (scripts[i].src != "") {
            var tag = document.createElement("script");
            tag.src = scripts[i].src;
            document.getElementsByTagName("head")[0].appendChild(tag);
        }
        else {
            eval(scripts[i].innerHTML);
        }
    }
}

Uwaga: chociaż evalmoże powodować lukę w zabezpieczeniach, jeśli nie jest używany prawidłowo, jest znacznie szybszy niż tworzenie tagu skryptu w locie.

DividedByZero
źródło
1
pomogło mi to, ale czuję się brudny używając eval. upewniając się, że tekst nie jest zagrożony, nie widzę luki.
Jan
@ random-user evalzostał zaprojektowany, aby skrzywdzić użytkowników. Każde dynamiczne wykonanie skryptu jest ryzykiem i dlatego CSP wywołuje je, 'unsafe-eval'ponieważ tak jest. Naruszasz także bezpieczeństwo swoich witryn, jeśli używasz ich w bibliotece, ponieważ nie mogą jej wyłączyć.
jonathanKingston
Testowanie tego w Chrome 44 powoduje nieskończoną pętlę, gdy wywoływana jest metoda appendChild, ponieważ zwiększa to wartość scripts.length.
Codewithcheese
4
Skrypty z tą srcwłaściwością zostaną pobrane asynchronicznie i wykonane w momencie nadejścia. Kolejność nie jest zachowywana. Skrypty wbudowane będą również wykonywane poza kolejnością, synchronicznie przed skryptami asynchronicznymi.
robert4
21

Nie należy używać właściwości innerHTML, ale raczej metody appendChild węzła: węzła w drzewie dokumentów [HTML DOM]. W ten sposób możesz później wywołać wstrzyknięty kod.

Upewnij się, że rozumiesz, że node.innerHTML to nie to samo co node.appendChild . Możesz poświęcić trochę czasu na dokumentację klienta JavaScript, aby uzyskać więcej informacji i model DOM. Mam nadzieję, że poniższe wskazówki pomogą ...

Wstrzykiwanie próbek działa:

<html>
<head>
<title>test</title>
<script language="javascript" type="text/javascript">
    function doOnLoad(){
        addScript('inject',"function foo(){ alert('injected'); }");
    }


    function addScript(inject,code){
        var _in = document.getElementById('inject');
        var scriptNode = document.createElement('script');
        scriptNode.innerHTML = code;
        _in.appendChild(scriptNode);
    }

</script>
</head>
<body onload="doOnLoad();">
    <div id="header">some content</div>
    <div id="inject"></div>
    <input type="button" onclick="foo(); return false;" value="Test Injected" />
</body>
</html>

pozdrowienia,

Andreas
źródło
2
Wreszcie ktoś, kto faktycznie trochę wyjaśnia problem, a nie wszystkie inne try this, look how clever I amodpowiedzi. Zasługuje na UV, dostał moje.
RiggsFolly,
ja uv to, ponieważ jest to najprostszy sposób na wstrzyknięcie kodu javascript, który jest wykonywany po wstrzyknięciu. Nie rozumiem tylko różnicy między dodawaniem za pomocą innerHTML, który nie jest wykonywany, a powyższym sposobem z appendChild, który wykonuje. Z powodzeniem wykorzystałem to do stworzenia dynamicznej strony ze skryptem od podstaw za pomocą socket.io
wetlip
2
var _in = document.getElementById(inject);, Myślę.
Ron Burk,
21

Uproszczona wersja ES6 odpowiedzi @ joshcomley z przykładem.

Bez JQuery, bez biblioteki, bez ewaluacji, bez zmiany DOM, po prostu czysty Javascript.

http://plnkr.co/edit/MMegiu?p=preview

var setInnerHTML = function(elm, html) {
  elm.innerHTML = html;
  Array.from(elm.querySelectorAll("script")).forEach( oldScript => {
    const newScript = document.createElement("script");
    Array.from(oldScript.attributes)
      .forEach( attr => newScript.setAttribute(attr.name, attr.value) );
    newScript.appendChild(document.createTextNode(oldScript.innerHTML));
    oldScript.parentNode.replaceChild(newScript, oldScript);
  });
}

Stosowanie

$0.innerHTML = HTML;    // does *NOT* run <script> tags in HTML
setInnerHTML($0, HTML); // does run <script> tags in HTML
allenhwkim
źródło
1
literówka: nazwa funkcji setInnerHtmlnie jestsetInnerHTML
pery mimon
Zauważ, że w połączonym plnkr nazwa funkcji to, setInnerHTMLale jest wywoływana setInnerHtmlz wnętrza runBfunkcji. Dlatego przykład nie działa
danbars
16

Wypróbuj ten fragment:

function stripAndExecuteScript(text) {
    var scripts = '';
    var cleaned = text.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(){
        scripts += arguments[1] + '\n';
        return '';
    });

    if (window.execScript){
        window.execScript(scripts);
    } else {
        var head = document.getElementsByTagName('head')[0];
        var scriptElement = document.createElement('script');
        scriptElement.setAttribute('type', 'text/javascript');
        scriptElement.innerText = scripts;
        head.appendChild(scriptElement);
        head.removeChild(scriptElement);
    }
    return cleaned;
};


var scriptString = '<scrip' + 't + type="text/javascript">alert(\'test\');</scr' + 'ipt><strong>test</strong>';
document.getElementById('element').innerHTML = stripAndExecuteScript(scriptString);
fantactuka
źródło
tak, ta metoda działa, ale pojawią się błędy, jeśli masz komentarze lub console.logs, więc uważaj na to, że możesz również zmodyfikować, aby uwzględnić moduły var modules = [] var cleaner = text.replace (/ <script ([^> ] *)> ([\ s \ S] *?) <\ / script> / gi, function (m, tags, script) {if (/type="module"/.test(tags)) {modules.push (skrypt) return} scripts + = script + '\ n' return ''})
zavr
13
function insertHtml(id, html)  
{  
   var ele = document.getElementById(id);  
   ele.innerHTML = html;  
   var codes = ele.getElementsByTagName("script");   
   for(var i=0;i<codes.length;i++)  
   {  
       eval(codes[i].text);  
   }  
}  

W moim projekcie działa w Chrome

Bruce
źródło
Szybko i ładnie. Dziękuję Ci.
Jorge Fuentes González,
Otóż ​​to! Dziękuję Ci.
Floris
7

Rozwiązanie bez użycia „eval”:

var setInnerHtml = function(elm, html) {
  elm.innerHTML = html;
  var scripts = elm.getElementsByTagName("script");
  // If we don't clone the results then "scripts"
  // will actually update live as we insert the new
  // tags, and we'll get caught in an endless loop
  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);
  }
}

To zasadniczo klonuje tag script, a następnie zastępuje zablokowany tag script nowym, co pozwala na wykonanie.

joshcomley
źródło
3

scriptNode.innerHTML = codenie działa dla IE. Jedyną rzeczą do zrobienia jest wymiana scriptNode.text = codei działa dobrze

Jorge
źródło
3

Łatwiej jest używać jquery $(parent).html(code)zamiast parent.innerHTML = code:

var oldDocumentWrite = document.write;
var oldDocumentWriteln = document.writeln;
try {
    document.write = function(code) {
        $(parent).append(code);
    }
    document.writeln = function(code) {
        document.write(code + "<br/>");
    }
    $(parent).html(html); 
} finally {
    $(window).load(function() {
        document.write = oldDocumentWrite
        document.writeln = oldDocumentWriteln
    })
}

Działa to również ze skryptami, które używają document.writei skryptami ładowanymi za pośrednictwem srcatrybutu. Niestety nawet to nie działa ze skryptami Google AdSense.

iirekm
źródło
1
Co sprawia, że ​​mówisz, że jest łatwiej? Nie jest nawet krótsza. Zawsze uważam, że nadużywanie jQuery to zły pomysł.
Manngo
2

Po prostu zrób:

document.body.innerHTML = document.body.innerHTML + '<img src="../images/loaded.gif" alt="" onload="alert(\'test\');this.parentNode.removeChild(this);" />';
Jagnięcina
źródło
1
wygląda na genialny pomysł
pery mimon
0

Możesz rzucić okiem na ten post . Kod może wyglądać następująco:

var actualDivToBeUpdated = document.getElementById('test');
var div = document.createElement('div');
div.innerHTML = '<script type="text/javascript">alert("test");<\/script>';
var children = div.childNodes;
actualDivToBeUpdated.innerHTML = '';
for(var i = 0; i < children.length; i++) {
    actualDivToBeUpdated.appendChild(children[i]);
}
Darin Dimitrov
źródło
0

Dzięki skryptowi Larry'ego, który działał doskonale w IE10, użyłem tego:

$('#' + id)[0].innerHTML = result;
$('#' + id + " script").each(function() { this.text = this.text || $(this).text();} );
AxD
źródło
0

Rozciągając się od Larry'ego. Zrobiłem to rekurencyjnie przeszukując cały blok i węzły potomne.
Skrypt będzie teraz wywoływał również zewnętrzne skrypty, które są określone parametrem src. Skrypty są dołączane do głowy zamiast wstawiać i umieszczane w kolejności, w jakiej zostały znalezione. Tak więc specjalnie zachowane są skrypty zamówień. Każdy skrypt jest wykonywany synchronicznie, podobnie jak przeglądarka obsługuje początkowe ładowanie DOM. Więc jeśli masz blok skryptu, który wywołuje jQuery z CDN, a następny węzeł skryptu używa jQuery ... Nie ma sprawy! Aha i oznaczyłem dołączone skrypty identyfikatorem serializowanym na podstawie tego, co ustawiłeś w parametrze tagu, abyś mógł znaleźć, co zostało dodane przez ten skrypt.

exec_body_scripts: function(body_el, tag) {
    // Finds and executes scripts in a newly added element's body.
    // Needed since innerHTML does not run scripts.
    //
    // Argument body_el is an element in the dom.

    function nodeName(elem, name) {
        return elem.nodeName && elem.nodeName.toUpperCase() ===
              name.toUpperCase();
    };

    function evalScript(elem, id, callback) {
        var data = (elem.text || elem.textContent || elem.innerHTML || "" ),
            head = document.getElementsByTagName("head")[0] ||
                      document.documentElement;

        var script = document.createElement("script");
        script.type = "text/javascript";
        if (id != '') {
            script.setAttribute('id', id);
        }

        if (elem.src != '') {
            script.src = elem.src;
            head.appendChild(script);
            // Then bind the event to the callback function.
            // There are several events for cross browser compatibility.
            script.onreadystatechange = callback;
            script.onload = callback;
        } else {
            try {
                // doesn't work on ie...
                script.appendChild(document.createTextNode(data));      
            } catch(e) {
                // IE has funky script nodes
                script.text = data;
            }
            head.appendChild(script);
            callback();
        }
    };

    function walk_children(node) {
        var scripts = [],
          script,
          children_nodes = node.childNodes,
          child,
          i;

        if (children_nodes === undefined) return;

        for (i = 0; i<children_nodes.length; i++) {
            child = children_nodes[i];
            if (nodeName(child, "script" ) &&
                (!child.type || child.type.toLowerCase() === "text/javascript")) {
                scripts.push(child);
            } else {
                var new_scripts = walk_children(child);
                for(j=0; j<new_scripts.length; j++) {
                    scripts.push(new_scripts[j]);
                }
            }
        }

        return scripts;
    }

    var i = 0;
    function execute_script(i) {
        script = scripts[i];
        if (script.parentNode) {script.parentNode.removeChild(script);}
        evalScript(scripts[i], tag+"_"+i, function() {
            if (i < scripts.length-1) {
                execute_script(++i);
            }                
        });
    }

    // main section of function
    if (tag === undefined) tag = 'tmp';

    var scripts = walk_children(body_el);

    execute_script(i);
}
BadOPCode
źródło
0

Spróbuj tego, działa u mnie w Chrome, Safari i Firefox:

var script = document.createElement('script');
script.innerHTML = 'console.log("hi")';
document.body.appendChild(script); 
--> logs "hi"

Należy jednak pamiętać, że następujący skrypt zagnieżdżony div NIE będzie działać:

var script = document.createElement('div');
script.innerHTML = '<script>console.log("hi")</script>';
document.body.appendChild(script);
--> doesn't log anything

Aby skrypt mógł zostać uruchomiony, musi zostać utworzony jako węzeł, a następnie dołączony jako element podrzędny. Możesz nawet dołączyć skrypt do wcześniej wstawionego div i będzie on działał (napotkałem to wcześniej, próbując uruchomić kod serwera reklam):

var div = document.createElement('div');
div.id = 'test-id';
document.body.appendChild(div);
var script = document.createElement('script');
script.innerHTML = 'console.log("hi")';
document.getElementById('test-id').appendChild(script);
--> logs "hi"
Trev14
źródło
0

Poszerzam odpowiedź Lambdera

document.body.innerHTML = '<img src="../images/loaded.gif" alt="" > onload="alert(\'test\');this.parentNode.removeChild(this);" />';

Możesz użyć obrazu base64, aby utworzyć i załadować swój skrypt

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMjHxIGmVAAAADUlEQVQYV2P4//8/AwAI/AL+iF8G4AAAAABJRU5ErkJggg=="
    onload="var script = document.createElement('script');  script.src = './yourCustomScript.js'; parentElement.append(script);" />

Lub jeśli masz Iframe, możesz go użyć zamiast tego

<iframe src='//your-orginal-page.com' style='width:100%;height:100%'
    onload="var script = document.createElement('script');  script.src = './your-coustom-script.js'; parentElement.append(script);"
    frameborder='0'></iframe>
pery mimon
źródło
0

Potrzebowałem czegoś podobnego, ale potrzebowałem, aby skrypt pozostał lub został ponownie utworzony w tym samym miejscu, co oryginalny skrypt, ponieważ mój skrypt jest ukierunkowany na lokalizację tagu skryptu w DOM, aby tworzyć / kierować elementy. Stworzyłem również skrypt rekurencyjny, aby upewnić się, że będzie działał również, jeśli jest o więcej niż jeden poziom niższy.

UWAGA: używam consttutaj, jeśli masz starszą przeglądarkę, po prostu użyj var.

    window.exec_body_scripts = function(body_el) {
        // ref: /programming/2592092/executing-script-elements-inserted-with-innerhtml based on Larry K's answer
        // Finds and executes scripts in a newly added element's body.
        // Needed since innerHTML does not run scripts.
        //
        // Argument body_el is an element in the dom.
        const
            type__Js = 'text/javascript',
            tagName__Script = 'script',
            tagName__Script__Upper = tagName__Script.toUpperCase();
        var scripts = [], script, i;
        function evalScript(elem) {
            var parent = elem.parentNode,
                data = (elem.text || elem.textContent || elem.innerHTML || ""),
                script = document.createElement(tagName__Script);

            script.type = type__Js;
            try {
                // doesn't work on ie...
                script.appendChild(document.createTextNode(data));
            } catch (e) {
                // IE has funky script nodes
                script.text = data;
            }
            // Make sure to re-insert the script at the same position
            // to make sure scripts that target their position
            // in the DOM function as expected.
            var parent = elem.parentNode;
            parent.insertBefore(script, elem);
            parent.removeChild(elem);
        };
        // Get all scripts (recursive)
        if (typeof (document.querySelectorAll) !== typeof (void 0)) {
            document.querySelectorAll('script').forEach((scr) => { if (!scr.type || scr.type.toLowerCase() === type__Js) scripts.push(scr); });
        }
        else {
            var children_nodes = body_el.childNodes, child;
            for (i = 0; children_nodes[i]; i++) {
                child = children_nodes[i];
                if (
                    child.nodeName
                    &&
                    child.nodeName.toUpperCase() === tagName__Script__Upper
                    &&
                    (
                        !child.type
                        ||
                        child.type.toLowerCase() === type__Js
                    )
                ) {
                    scripts.push(child);
                }
                // Recursive call
                window.exec_body_scripts(child);
            }
        }
        for (i = 0; scripts[i]; i++) {
            evalScript(scripts[i]);
        }
    };
NKCSS
źródło
0

Stworzyłem tę nową funkcję pomocnika w TypeScript, może ktoś to doceni. Jeśli usuniesz deklarację typu z parametru skryptu, będzie to zwykły JS.

const evalPageScripts = () => {
  const scripts = document.querySelectorAll('script');

  scripts.forEach((script: HTMLScriptElement) => {
    const newScript = document.createElement('script');
    newScript.type = 'text/javascript';
    newScript.src = script.src;

    if (script.parentNode) {
      script.parentNode.removeChild(script);
    }

    return document.body.appendChild(newScript);
  })
};

export default evalPageScripts;

kvba
źródło
-1

Wypróbuj funkcję eval ().

data.newScript = '<script type="text/javascript">//my script...</script>'
var element = document.getElementById('elementToRefresh');
element.innerHTML = data.newScript;
eval(element.firstChild.innerHTML);

To prawdziwy przykład z projektu, który rozwijam. Dzięki temu wpisowi

IgniteCoders
źródło
-1

Oto moje rozwiązanie w ostatnim projekcie.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Sample</title>
</head>
<body>
<h1 id="hello_world">Sample</h1>
<script type="text/javascript">
 var div = document.createElement("div");
  var t = document.createElement('template');
  t.innerHTML =  "Check Console tab for javascript output: Hello world!!!<br/><script type='text/javascript' >console.log('Hello world!!!');<\/script>";
  
  for (var i=0; i < t.content.childNodes.length; i++){
    var node = document.importNode(t.content.childNodes[i], true);
    div.appendChild(node);
  }
 document.body.appendChild(div);
</script>
 
</body>
</html>

Szary
źródło