Menjalankan elemen <script> yang disisipkan dengan .innerHTML

111

Saya punya skrip yang memasukkan beberapa konten ke dalam elemen menggunakan innerHTML.

Konten tersebut misalnya bisa berupa:

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

Masalahnya adalah kode di dalam <script>tag tidak dieksekusi. Saya googling sedikit tetapi tidak ada solusi yang jelas. Jika saya memasukkan konten menggunakan jQuery $(element).append(content);, bagian skrip sudah didapat evalsebelum dimasukkan ke DOM.

Adakah yang punya potongan kode yang mengeksekusi semua <script>elemen? Kode jQuery agak rumit jadi saya tidak bisa benar-benar mengetahui bagaimana hal itu dilakukan.

Edit :

Dengan mengintip kode jQuery, saya telah berhasil mengetahui bagaimana jQuery melakukannya, yang menghasilkan kode berikut:

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
sumber
1
Mengapa Anda tidak bisa hanya mengulang turunan elemen, dan untuk setiap elemen yang merupakan elemen skrip Anda hanya mengevaluasi () innerHtml dari anak itu? Beginilah cara saya melihatnya dilakukan oleh vendor komponen besar, setiap kali mereka menyelesaikan callback ajax yang menambahkan barang ke DOM, mereka melakukan persis seperti itu. Ingatlah bahwa ini bisa lambat, terutama di IE7.
slugster
2
Andreas: Jika saya menambahkan fungsi, misalnya function testFunction(){ alert('test'); }ke kode yang dimasukkan ke innerHTML, lalu mencoba memanggilnya, dikatakan bahwa fungsi tersebut tidak ditentukan.
phidah
1
Phidah yang luar biasa, bekerja seperti pesona, tepuk tangan
Marcin
3
Saya pikir sangat penting untuk memahami bahwa ini adalah perilaku yang dimaksudkan oleh browser untuk mencegah serangan skrip lintas situs. Jika teks yang Anda setel sebagai innerHTML disediakan oleh Bob, itu akan dieksekusi di browser Alice yang menyebabkan kerusakan (pikirkan forum tempat orang dapat menulis komentar dengan menambahkan tag skrip ke dalamnya). Anda dapat membaca lebih lanjut di sini: en.wikipedia.org/wiki/Cross-site_scripting . Tetap aman!
Xatian
1
HTML banyak berubah sejak 2010. Saat ini, mungkin Anda ingin melihat: stackoverflow.com/a/58862506/890357
marciowb

Jawaban:

27

Skrip OP tidak berfungsi di IE 7. Dengan bantuan dari SO, inilah skrip yang berfungsi:

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
sumber
4
Lebih baik gunakan jQuery $(parent).html(code)- lihat jawaban saya di bawah.
iirekm
setelah skrip dimasukkan ke DOM, bagaimana cara menghapusnya?
S4beR
1
Skripnya tidak rekursif, jadi hanya akan melihat turunan langsung. Ini bekerja untuk saya:if (nodeName(child, "script" ) && (!child.type || child.type.toLowerCase() === "text/javascript")) { scripts.push(child); } else { exec_body_scripts(child); }
st4wik
2
Perhatikan bahwa kode di atas tidak mengeksekusi skrip yang dimuat melalui src. Skrip di atas dapat diubah untuk memeriksa elem.srcdan secara bersyarat mengatur srcproperti dari elemen skrip yang dibuat alih-alih mengatur konten teksnya.
Ryan Morlok
Mengapa tidak menggunakan trik globaleval daripada membuat <script>elemen dan memasukkannya ke <head>? Keduanya mengeksekusi kode JS tanpa mengekspos penutupan saat ini.
Finesse
31

@phidah ... Berikut adalah solusi yang sangat menarik untuk masalah Anda: http://24ways.org/2005/have-your-dom-and-script-it-too

Jadi akan terlihat seperti ini:

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

pengguna447963
sumber
2
dan bahkan lebih baik, tidak perlu memiliki gambar dengan acara "onerror", bagus untuk injeksi XSS cepat jvfconsulting.com/blog/47/… :)
baptx
11
Anda dapat menggunakan <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" onload="alert('test');">jika Anda ingin mencegah permintaan http tidak berguna.
Savas Vedova
1
suka ! (ditambahkan style="display:none;) untuk menyembunyikan ikon gambar rusak
keris
Sebenarnya, <style>lebih baik daripada <img>, karena tidak membuat permintaan jaringan
basin
23

Berikut ini skrip yang lebih pendek dan lebih efisien yang juga berfungsi untuk skrip dengan srcproperti:

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

Catatan: meskipun evaldapat menyebabkan kerentanan keamanan jika tidak digunakan dengan benar, ini jauh lebih cepat daripada membuat tag skrip dengan cepat.

DividedByZero
sumber
1
ini membantu saya tetapi saya merasa kotor menggunakan eval. memastikan teks tidak dapat dikompromikan saya tidak melihat kerentanan.
Yohanes
@ random-user evaldirancang untuk melukai pengguna. Eksekusi skrip dinamis apa pun adalah risiko dan inilah mengapa CSP memanggilnya 'unsafe-eval'karena memang demikian. Anda juga merusak keamanan situs Anda jika Anda menggunakannya di perpustakaan karena mereka tidak dapat mematikannya.
jonathanKingston
Menguji ini di Chrome 44 menyebabkan loop tak terbatas ketika appendChild dipanggil karena ini menambah nilai scripts.length.
Codewithcheese
4
Skrip dengan srcproperti akan diunduh secara asinkron dan dijalankan saat tiba. Pemesanan tidak dipertahankan. Skrip sebaris juga akan dieksekusi rusak, serentak sebelum asinkron.
robert4
21

Anda tidak boleh menggunakan properti innerHTML melainkan metode appendChild dari Node: sebuah simpul di pohon dokumen [HTML DOM]. Dengan cara ini Anda nantinya dapat memanggil kode yang Anda masukkan.

Pastikan Anda memahami bahwa node.innerHTML itu tidak sama dengan node.appendChild . Anda mungkin ingin meluangkan waktu pada Referensi Klien Javascript untuk detail lebih lanjut dan DOM. Semoga berikut membantu ...

Pekerjaan injeksi sampel:

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

salam,

Andreas
sumber
2
Akhirnya seseorang yang benar-benar menjelaskan sedikit tentang masalah daripada semua try this, look how clever I amjawaban lainnya . Layak mendapatkan UV, itu milikku.
RiggsFolly
i uv ini karena ini adalah cara paling sederhana untuk menyuntikkan kode javascript yang dijalankan setelah menyuntikkan. Saya hanya tidak memahami perbedaan antara menambahkan dengan innerHTML yang tidak dijalankan, dan cara di atas dengan appendChild yang dijalankan. Saya menggunakan ini dengan sukses untuk membuat halaman dinamis dengan skrip dari awal dengan socket.io
wetlip
2
var _in = document.getElementById(inject);, Kupikir.
Ron Burk
21

Versi ES6 yang disederhanakan dari jawaban @ joshcomley dengan sebuah contoh.

Tanpa JQuery, Tanpa library, Tanpa eval, Tanpa perubahan DOM, Hanya Javascript murni.

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

Pemakaian

$0.innerHTML = HTML;    // does *NOT* run <script> tags in HTML
setInnerHTML($0, HTML); // does run <script> tags in HTML
allenhwkim.dll
sumber
1
salah ketik: nama fungsinya setInnerHtmlbukansetInnerHTML
pery mimon
Perhatikan bahwa di plnkr yang ditautkan, nama fungsinya adalah setInnerHTMLtetapi dipanggil setInnerHtmldari dalam runBfungsi. Oleh karena itu contoh tidak berhasil
danbars
16

Coba cuplikan ini:

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
sumber
ya metode ini berfungsi tetapi Anda akan mendapatkan kesalahan jika Anda memiliki komentar atau console.logs jadi hati-hati untuk itu juga Anda dapat mengubah ke akun untuk modules var modules = [] var clean = text.replace (/ <script ([^> ] *)> ([\ s \ S] *?) <\ / script> / gi, fungsi (m, tag, skrip) {if (/type="module"/.test(tags)) {modules.push (script) return} skrip + = skrip + '\ 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);  
   }  
}  

Ini berfungsi di Chrome dalam proyek saya

Bruce
sumber
Cepat dan cantik. Terima kasih.
Jorge Fuentes González
Itu dia! Terima kasih.
Floris
7

Solusi tanpa menggunakan "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);
  }
}

Ini pada dasarnya menggandakan tag skrip dan kemudian mengganti tag skrip yang diblokir dengan yang baru dibuat, sehingga memungkinkan eksekusi.

joshcomley
sumber
3

scriptNode.innerHTML = codetidak bekerja untuk IE. Satu-satunya hal yang harus dilakukan adalah mengganti dengan scriptNode.text = codedan itu berfungsi dengan baik

Jorge
sumber
3

Lebih mudah menggunakan jquery $(parent).html(code)daripada 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
    })
}

Ini juga berfungsi dengan skrip yang menggunakan document.writedan skrip dimuat melalui srcatribut. Sayangnya bahkan ini tidak berfungsi dengan skrip Google AdSense.

iirekm
sumber
1
Apa yang membuat Anda mengatakan itu lebih mudah? Ini bahkan tidak lebih pendek. Saya selalu berpikir bahwa menggunakan jQuery secara berlebihan adalah ide yang buruk.
Manngo
2

Kerjakan saja:

document.body.innerHTML = document.body.innerHTML + '<img src="../images/loaded.gif" alt="" onload="alert(\'test\');this.parentNode.removeChild(this);" />';
Lambder
sumber
1
terlihat seperti ide jenius
pery mimon
0

Anda dapat melihat posting ini . Kode tersebut mungkin terlihat seperti ini:

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

Berkat skrip Larry, yang bekerja dengan baik di IE10, inilah yang saya gunakan:

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

Memperluas dari Larry's. Saya membuatnya secara rekursif mencari seluruh blok dan node anak.
Skrip sekarang juga akan memanggil skrip eksternal yang ditentukan dengan parameter src. Skrip ditambahkan ke head, bukan disisipkan dan ditempatkan sesuai urutan ditemukannya. Jadi skrip pesanan secara khusus dipertahankan. Dan setiap skrip dijalankan secara sinkron mirip dengan cara browser menangani pemuatan DOM awal. Jadi jika Anda memiliki blok skrip yang memanggil jQuery dari CDN dan kemudian simpul skrip berikutnya menggunakan jQuery ... Tidak masalah! Oh dan saya menandai skrip yang ditambahkan dengan id serial berdasarkan apa yang Anda tetapkan di parameter tag sehingga Anda dapat menemukan apa yang ditambahkan oleh skrip ini.

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

Coba ini, ini berfungsi untuk saya di Chrome, Safari & Firefox:

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

Satu hal yang perlu diperhatikan, adalah bahwa skrip bertingkat div berikut TIDAK akan berjalan:

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

Untuk menjalankan skrip itu harus dibuat sebagai node kemudian ditambahkan sebagai anak. Anda bahkan dapat menambahkan skrip di dalam div yang dimasukkan sebelumnya & itu akan berjalan (Saya pernah mengalami ini sebelumnya ketika mencoba untuk membuat kode server iklan berfungsi):

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

Menghabiskan jawaban Lambder

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

Anda dapat menggunakan gambar base64 untuk membuat dan memuat skrip Anda

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

Atau jika Anda memiliki, IframeAnda dapat menggunakannya sebagai gantinya

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

Saya membutuhkan sesuatu yang serupa, tetapi membutuhkan skrip untuk tetap atau dibuat ulang di tempat yang sama dengan skrip asli, karena skrip saya menargetkan lokasi tag skrip di DOM untuk membuat / menargetkan elemen. Saya juga membuat skrip rekursif untuk memastikannya juga berfungsi jika lebih dari satu level ke bawah.

CATATAN: Saya gunakan di constsini, jika Anda memiliki browser yang lebih lama, gunakan saja 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
sumber
0

Membuat fungsi pembantu baru ini di TypeScript, mungkin seseorang akan menghargainya. Jika Anda menghapus deklarasi tipe dari parameter skrip, itu hanya akan menjadi JS biasa.

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

Coba fungsi eval ().

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

Ini adalah contoh nyata dari proyek yang saya kembangkan. Terima kasih untuk posting ini

IgniteCoders
sumber
-1

Inilah solusi saya dalam proyek terbaru.

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

Abu-abu
sumber