Ausführen von mit .innerHTML eingefügten <script> -Elementen


111

Ich habe ein Skript, das mithilfe von Inhalten Inhalte in ein Element einfügt innerHTML.

Der Inhalt könnte zum Beispiel sein:

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

Das Problem ist, dass der Code im <script>Tag nicht ausgeführt wird. Ich habe ein bisschen gegoogelt, aber es gab keine offensichtlichen Lösungen. Wenn ich den Inhalt mit jQuery eingefügt habe, wurden $(element).append(content);die Skriptteile evalvor dem Einfügen in das DOM erstellt.

Hat jemand einen Codeausschnitt, der alle <script>Elemente ausführt ? Der jQuery-Code war etwas komplex, so dass ich nicht wirklich herausfinden konnte, wie es gemacht wurde.

Bearbeiten :

Durch einen Blick in den jQuery-Code konnte ich herausfinden, wie jQuery dies tut, was zu folgendem Code führte:

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>

1
Warum können Sie nicht einfach die untergeordneten Elemente des Elements iterieren und für jedes Element, das ein Skriptelement ist, nur das innere HTML dieses untergeordneten Elements auswerten ()? So habe ich es von einem großen Komponentenhersteller gesehen, jedes Mal, wenn er einen Ajax-Rückruf durchführt, der dem DOM Dinge hinzufügt, tun sie genau das. Bedenken Sie jedoch, dass es langsam sein kann, insbesondere in IE7.
Slugster

2
Andreas: Wenn ich eine Funktion hinzufüge, zum Beispiel function testFunction(){ alert('test'); }zu dem in innerHTML eingefügten Code, und dann versuche, sie aufzurufen, heißt es, dass die Funktion nicht definiert ist.
Phidah

1
Ehrfürchtige Phidah, wirkt wie Charme, Prost
Marcin

3
Ich denke, es ist absolut wichtig zu verstehen, dass dies ein beabsichtigtes Verhalten des Browsers ist, um Cross-Site-Scripting-Angriffe zu verhindern. Wenn der von Ihnen als innerHTML festgelegte Text von Bob bereitgestellt wird, wird er in Alices Browser ausgeführt und verursacht Schaden (stellen Sie sich ein Forum vor, in dem Benutzer Kommentare schreiben können, die ihnen Skript-Tags hinzufügen). Sie können hier mehr darüber lesen: en.wikipedia.org/wiki/Cross-site_scripting . Bleib sicher!
Xatian

1
Ein HTML hat sich seit 2010 stark verändert. In diesen Tagen möchten Sie vielleicht einen Blick darauf werfen: stackoverflow.com/a/58862506/890357
marciowb

Antworten:


27

Das Skript des OP funktioniert in IE 7 nicht. Mit Hilfe von SO ist hier ein Skript, das Folgendes tut:

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]);
  }
};

4
Verwenden Sie besser jQuery's $(parent).html(code)- siehe meine Antwort unten.
Iirekm

Wie soll ich das Skript entfernen, nachdem es in DOM eingefügt wurde?
S4beR

1
Das Skript ist nicht rekursiv und betrachtet nur direkte untergeordnete Elemente. Das funktioniert bei mir:if (nodeName(child, "script" ) && (!child.type || child.type.toLowerCase() === "text/javascript")) { scripts.push(child); } else { exec_body_scripts(child); }
st4wik

2
Beachten Sie, dass der obige Code keine Skripte ausführt, die über src geladen werden. Das obige Skript kann geändert werden, um elem.srcdie srcEigenschaft des erstellten Skriptelements zu überprüfen und bedingt festzulegen, anstatt dessen Textinhalt festzulegen.
Ryan Morlok

Warum nicht den globalen evalTrick verwenden, anstatt ein <script>Element zu erstellen und es in das einzufügen <head>? Beide führen JS-Code aus, ohne den aktuellen Abschluss verfügbar zu machen.
Finesse

31

@phidah ... Hier ist eine sehr interessante Lösung für Ihr Problem: http://24ways.org/2005/have-your-dom-and-script-it-too

Also würde es stattdessen so aussehen:

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


2
und noch besser, kein Bild mit "onerror" -Ereignis
erforderlich

11
Sie können verwenden, <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" onload="alert('test');">wenn Sie eine nutzlose http-Anforderung verhindern möchten.
Savas Vedova

1
Liebe es ! (hinzugefügt style="display:none;), um das Symbol für kaputte Bilder zu verbergen
kris

Eigentlich <style>ist es besser als <img>, weil es keine Netzwerkanfrage macht
Becken

23

Hier ist ein kürzeres, effizienteres Skript, das auch für Skripte mit der srcEigenschaft funktioniert :

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);
        }
    }
}

Hinweis: evalWenn es nicht ordnungsgemäß verwendet wird, kann es zwar zu einer Sicherheitslücke kommen, es ist jedoch viel schneller als das Erstellen eines Skript-Tags im laufenden Betrieb.


1
das hat mir geholfen, aber ich fühle mich schmutzig mit eval. Um sicherzustellen, dass Text nicht kompromittiert werden kann, sehe ich keine Sicherheitslücke.
John

@ random-user evalwurde entwickelt, um Benutzer zu verletzen. Jede dynamische Skriptausführung ist ein Risiko, und deshalb ruft CSP sie auf, 'unsafe-eval'weil sie es ist. Sie beeinträchtigen auch die Sicherheit Ihrer Websites, wenn Sie sie in einer Bibliothek verwenden, da sie diese nicht deaktivieren können.
JonathanKingston

Das Testen in Chrome 44 führt beim Aufruf von appendChild zu einer Endlosschleife, da dadurch der Wert scripts.length erhöht wird.
Codewithcheese

4
Skripte mit der srcEigenschaft werden asynchron heruntergeladen und bei Ankunft ausgeführt. Bestellung bleibt nicht erhalten. Inline-Skripte werden auch außerhalb der Reihenfolge synchron vor den asynchronen ausgeführt.
Robert4

21

Sie sollten nicht die innerHTML-Eigenschaft verwenden, sondern die appendChild-Methode des Knotens: einen Knoten in einem Dokumentbaum [HTML DOM]. Auf diese Weise können Sie später Ihren injizierten Code aufrufen.

Stellen Sie sicher, dass Sie verstehen, dass dies node.innerHTML nicht dasselbe ist wie node.appendChild . Möglicherweise möchten Sie einige Zeit in der Javascript-Client-Referenz verbringen, um weitere Informationen und das DOM zu erhalten. Hoffe das Folgende hilft ...

Probeninjektion funktioniert:

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

Grüße,


2
Endlich jemand, der eher ein bisschen über das Problem erklärt als alle anderen try this, look how clever I amAntworten. Verdient eine UV, es hat meine.
RiggsFolly

Dies ist der einfachste Weg, um Javascript-Code zu injizieren, der nach dem Injizieren ausgeführt wird. Ich verstehe nur nicht den Unterschied zwischen dem Hinzufügen mit innerHTML, das nicht ausgeführt wird, und dem obigen Weg mit appendChild, das ausgeführt wird. Ich habe dies erfolgreich verwendet, um eine dynamische Seite mit Skript von Grund auf mit socket.io
wetlip

2
var _in = document.getElementById(inject);, Meiner Ansicht nach.
Ron Burk

21

Vereinfachte ES6-Version von @ joshcomleys Antwort mit einem Beispiel.

Keine JQuery, keine Bibliothek, keine Auswertung, keine DOM-Änderung, nur reines 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);
  });
}

Verwendung

$0.innerHTML = HTML;    // does *NOT* run <script> tags in HTML
setInnerHTML($0, HTML); // does run <script> tags in HTML

1
Tippfehler: Der Name der Funktion ist setInnerHtmlnichtsetInnerHTML
pery mimon

Beachten Sie, dass in dem verknüpften plnkr der Funktionsname lautet, setInnerHTMLaber setInnerHtmlinnerhalb der runBFunktion aufgerufen wird . Daher funktioniert das Beispiel nicht
Danbars

16

Probieren Sie dieses Snippet aus:

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

Ja, diese Methode funktioniert, aber Sie erhalten Fehler, wenn Sie Kommentare oder console.logs haben. Achten Sie also darauf, dass Sie auch Änderungen vornehmen können, um Module zu berücksichtigen. var modules = [] var clean = text.replace (/ <script ([^>) ] *)> ([\ s \ S] *?) <\ / script> / gi, Funktion (m, Tags, Skript) {if (/type="module"/.test(tags)) {modules.push (script) 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);  
   }  
}  

Es funktioniert in Chrome in meinem Projekt


Schnell und hübsch. Danke dir.
Jorge Fuentes González

Das ist es! Danke dir.
Floris

7

Eine Lösung ohne "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);
  }
}

Dies klont im Wesentlichen das Skript-Tag und ersetzt dann das blockierte Skript-Tag durch das neu generierte, wodurch die Ausführung ermöglicht wird.


3

scriptNode.innerHTML = codefunktionierte nicht für IE. Das einzige, was zu tun ist, ist durch zu ersetzen scriptNode.text = codeund es funktioniert gut


3

Es ist einfacher, jquery zu verwenden, $(parent).html(code)anstatt 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
    })
}

Dies funktioniert auch mit Skripten, die document.writeSkripte verwenden und über srcAttribute geladen werden . Leider funktioniert auch dies nicht mit Google AdSense-Skripten.


1
Was lässt Sie sagen, dass es einfacher ist? Es ist nicht noch kürzer. Ich denke immer, dass eine übermäßige Verwendung von jQuery eine schlechte Idee ist.
Manngo

2

Mach einfach:

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

1
sehen aus wie eine geniale Idee
pery mimon

0

Sie können einen Blick auf diesen Beitrag werfen . Der Code könnte folgendermaßen aussehen:

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]);
}

0

Dank Larrys Skript, das in IE10 perfekt funktioniert hat, habe ich Folgendes verwendet:

$('#' + id)[0].innerHTML = result;
$('#' + id + " script").each(function() { this.text = this.text || $(this).text();} );

0

Ausdehnung von Larry. Ich habe es rekursiv gemacht, den gesamten Block und die untergeordneten Knoten zu durchsuchen.
Das Skript ruft jetzt auch externe Skripte auf, die mit dem Parameter src angegeben werden. Skripte werden an den Kopf angehängt, anstatt eingefügt und in der Reihenfolge platziert, in der sie gefunden wurden. So bleiben speziell Bestellskripte erhalten. Und jedes Skript wird synchron ausgeführt, ähnlich wie der Browser das anfängliche Laden des DOMs handhabt. Wenn Sie also einen Skriptblock haben, der jQuery von einem CDN aufruft und dann der nächste Skriptknoten jQuery verwendet ... Kein Problem! Oh, und ich habe die angehängten Skripte mit einer serialisierten ID versehen, die auf dem basiert, was Sie im Tag-Parameter festgelegt haben, damit Sie herausfinden können, was von diesem Skript hinzugefügt wurde.

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);
}

0

Versuchen Sie dies, es funktioniert für mich auf Chrome, Safari & Firefox:

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

Beachten Sie jedoch, dass das folgende div-verschachtelte Skript NICHT ausgeführt wird:

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

Damit ein Skript ausgeführt werden kann, muss es als Knoten erstellt und dann als untergeordnetes Element angehängt werden. Sie können sogar ein Skript in ein zuvor injiziertes div anhängen und es wird ausgeführt (ich bin bereits darauf gestoßen, als ich versucht habe, den Ad-Server-Code zum Laufen zu bringen):

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"

0

Die Antwort von Lambder ausgeben

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

Sie können das base64-Image verwenden, um Ihr Skript zu erstellen und zu laden

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

Oder wenn Sie eine haben Iframe, können Sie sie stattdessen verwenden

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

0

Ich brauchte etwas Ähnliches, aber das Skript musste an derselben Stelle wie das ursprüngliche Skript verbleiben oder neu erstellt werden, da mein Skript auf die Position des Skript-Tags im DOM abzielt, um / Zielelemente zu erstellen. Ich habe das Skript auch rekursiv gemacht, um sicherzustellen, dass es auch funktioniert, wenn es mehr als eine Ebene tiefer liegt.

HINWEIS: Ich verwende consthier, wenn Sie einen älteren Browser haben, verwenden Sie einfach 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]);
        }
    };

0

Diese neue Hilfsfunktion wurde in TypeScript erstellt. Vielleicht wird es jemand zu schätzen wissen. Wenn Sie die Typdeklaration aus dem Skriptparameter entfernen, handelt es sich nur um einfaches 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;


-1

Versuchen Sie die Funktion eval ().

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

Dies ist ein echtes Beispiel aus einem Projekt, das ich entwickle. Danke an diesen Beitrag


-1

Hier ist meine Lösung in einem aktuellen Projekt.

<!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>

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.