.İnnerHTML ile eklenen <script> öğeleri çalıştırılıyor


112

Kullanarak bir öğeye içerik ekleyen bir komut dosyam var innerHTML.

İçerik örneğin şunlar olabilir:

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

Sorun, <script>etiketin içindeki kodun çalıştırılmamasıdır. Google'da biraz araştırdım ama görünen bir çözüm yoktu. İçeriği jQuery kullanarak eklersem $(element).append(content);, komut dosyası bölümleri evalDOM'a enjekte edilmeden önce 'd aldı .

Tüm <script>öğeleri çalıştıran bir kod parçacığı olan var mı? JQuery kodu biraz karmaşıktı, bu yüzden nasıl yapıldığını gerçekten anlayamadım.

Düzenle :

JQuery koduna göz atarak jQuery'nin bunu nasıl yaptığını anlamayı başardım, bu da aşağıdaki kodla sonuçlandı:

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
Neden öğenin alt öğelerini yineleyemiyorsunuz ve bir komut dosyası öğesi olan her biri için yalnızca o çocuğun innerHtml'sini değerlendiriyorsunuz ()? Bunu büyük bir bileşen satıcısı tarafından nasıl yapıldığını gördüm, her seferinde bir ajax geri araması tamamladıklarında DOM'a bir şeyler eklediler. Özellikle IE7'de yavaş olabileceğini aklınızda bulundurun.
slugster

2
Andreas: Örneğin function testFunction(){ alert('test'); }innerHTML'ye eklenen koda bir işlev eklersem ve sonra onu çağırmayı denersem, işlevin tanımlı olmadığını söyler.
phidah

1
Müthiş phidah, çekicilik gibi çalışır, alkışlar
Marcin

3
Bunun, siteler arası komut dosyası çalıştırma saldırılarını önlemek için tarayıcının amaçladığı davranış olduğunu anlamanın kesinlikle önemli olduğunu düşünüyorum. İnnerHTML olarak ayarladığınız metin Bob tarafından sağlandıysa, Alice'in tarayıcısında çalışarak hasara neden olur (insanların kendilerine komut etiketleri ekleyerek yorumlar yazabilecekleri bir forum düşünün). Bununla ilgili daha fazla bilgiyi buradan okuyabilirsiniz: en.wikipedia.org/wiki/Cross-site_scripting . Kurtarılmaya devam edin!
Xatian

1
Bir HTML 2010'dan beri çok değişti. Bugünlerde belki bakmak istersiniz: stackoverflow.com/a/58862506/890357
marciowb

Yanıtlar:


27

OP'nin senaryosu IE 7'de çalışmıyor. SO'nun yardımıyla, işte bunu yapan bir betik:

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
Daha iyi jQuery kullanın $(parent).html(code)- aşağıdaki cevabıma bakın.
iirekm

komut dosyası DOM'a enjekte edildiğinde, onu nasıl kaldırmalıyım?
S4beR

1
Komut dosyası özyinelemeli değildir, bu nedenle yalnızca doğrudan çocuklara bakacaktır. Bu benim için çalışıyor:if (nodeName(child, "script" ) && (!child.type || child.type.toLowerCase() === "text/javascript")) { scripts.push(child); } else { exec_body_scripts(child); }
st4wik

2
Yukarıdaki kodun src aracılığıyla yüklenen komut dosyalarını çalıştırmadığını unutmayın. Yukarıdaki komut dosyası, metin içeriğini ayarlamak yerine oluşturulan komut dosyası öğesinin özelliğini kontrol etmek elem.srcve koşullu olarak ayarlamak için değiştirilebilir src.
Ryan Morlok

Neden bir öğe oluşturmak ve onu eklemek yerine küresel evalnumarayı kullanmayalım ? Her ikisi de mevcut kapanışı göstermeden JS kodunu yürütür. <script><head>
Finesse

31

@phidah ... İşte probleminize çok ilginç bir çözüm: http://24ways.org/2005/have-your-dom-and-script-it-too

Yani bunun yerine şöyle görünecektir:

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


2
ve daha da iyisi, "onerror" olaylı bir görüntüye gerek yok, hızlı XSS ​​enjeksiyonu için güzel jvfconsulting.com/blog/47/… :)
baptx

11
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" onload="alert('test');">Yararsız bir http talebini önlemek istiyorsanız kullanabilirsiniz .
Savas Vedova

1
Sevdim ! (eklendi style="display:none;) kırık görüntü simgesini gizlemek için
kris

Aslında, <style>daha iyidir <img>, bir ağ isteği yapmaz, çünkü
havzası

24

Burada, srcözelliğe sahip komut dosyaları için de çalışan daha kısa ve daha verimli bir komut dosyası verilmiştir :

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

Not: evalDüzgün kullanılmadığı takdirde bir güvenlik açığına neden olabilirken , anında bir komut dosyası etiketi oluşturmaktan çok daha hızlıdır.


1
bu bana yardımcı oldu, ancak eval'u kullanırken kendimi kirli hissediyorum. metnin tehlikeye atılamayacağından emin olmak bir güvenlik açığı görmüyorum.
John

@ random-user eval, kullanıcılara zarar vermek için tasarlanmıştır. Herhangi bir dinamik komut dosyası yürütme bir risktir ve bu nedenle CSP, öyle 'unsafe-eval'olduğu için onu çağırır . Ayrıca, sitenizi bir kitaplıkta kullanıyorsanız, kapatamayacakları için sitelerinizin güvenliğini de bozuyorsunuz.
jonathanKingston

Bunu Chrome 44'te test etmek, scripts.length değerini artırdığından appendChild çağrıldığında sonsuz bir döngüye neden olur.
Codewithcheese

4
Özelliğe sahip komut dosyaları srceşzamansız olarak indirilecek ve geldiği gibi çalıştırılacaktır. Sıralama korunmaz. Satır içi komut dosyaları da zaman uyumsuz olanlardan önce eşzamanlı olarak sıra dışı çalıştırılır.
robert4

21

İç HTML özelliğini değil, Node'un appendChild yöntemini kullanmalısınız: belge ağacındaki bir düğüm [HTML DOM]. Bu şekilde, daha sonra enjekte edilen kodunuzu arayabilirsiniz.

Bunun node.innerHTML ile aynı şey olmadığını anladığınızdan emin olun node.appendChild. Daha fazla ayrıntı ve DOM için Javascript İstemci Referansı üzerinde biraz zaman harcamak isteyebilirsiniz. Umarım aşağıdakiler yardımcı olur ...

Örnek enjeksiyon çalışır:

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

Saygılarımızla,


2
Sonunda, diğer tüm try this, look how clever I amcevaplardan ziyade konu hakkında biraz açıklama yapan biri . UV'yi hak ediyor, benimkini aldı.
RiggsFolly

i bunu uv çünkü enjekte ettikten sonra çalışan javascript kodunu enjekte etmenin en basit yoludur. Ben sadece çalıştırılmayan innerHTML ile ekleme ile çalıştırılan appendChild ile yukarıdaki yol arasındaki farkı anlamıyorum. Soket.io ile sıfırdan komut dosyasıyla dinamik bir sayfa oluşturmak için bunu başarıyla kullandım
wetlip

2
var _in = document.getElementById(inject);, Bence.
Ron Burk

21

@ Joshcomley'in cevabının bir örnekle basitleştirilmiş ES6 versiyonu.

JQuery yok, kütüphane yok, değerlendirme yok, DOM değişikliği yok, sadece saf 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);
  });
}

Kullanım

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

1
yazım hatası: işlevin adı setInnerHtmldeğilsetInnerHTML
pery mimon

Bağlanan plnkr'da işlev adı olduğunu setInnerHTMLancak işlevin setInnerHtmliçinden çağrıldığını unutmayın runB. Bu nedenle örnek işe yaramıyor
danbars

16

Bu pasajı deneyin:

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

evet bu yöntem işe yarar, ancak yorumlarınız veya console.log'larınız varsa hatalar alırsınız, bu yüzden buna dikkat edin, ayrıca modülleri hesaba katmak için değişiklik yapabilirsiniz var module = [] var temizlendi = metin.replace (/ <script ([^> ] *)> ([\ s \ S] *?) <\ / script> / gi, function (m, etiketler, script) {if (/type="module"/.test(tags)) {modules.push (script) return} betikleri + = 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);  
   }  
}  

Projemde Chrome'da çalışıyor


Hızlı ve güzel. Teşekkür ederim.
Jorge Fuentes González

Bu kadar! Teşekkür ederim.
Floris

7

"Eval" kullanmadan bir çözüm:

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

Bu, esasen komut dosyası etiketini klonlar ve ardından engellenen komut dosyası etiketini yeni oluşturulmuş olanla değiştirir, böylece yürütülmesine izin verir.


3

scriptNode.innerHTML = codeIE için çalışmadı. Yapılması gereken tek şey, ile değiştirmektir scriptNode.text = codeve sorunsuz çalışır


3

Bunun $(parent).html(code)yerine jquery kullanmak daha kolaydır 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
    })
}

Bu document.write, srcöznitelik aracılığıyla yüklenen komut dosyalarıyla ve kullanan komut dosyalarıyla da çalışır . Ne yazık ki bu bile Google AdSense komut dosyalarıyla çalışmıyor.


1
Daha kolay olduğunu söyleten nedir? Daha kısa bile değil. Her zaman jQuery'yi aşırı kullanmanın kötü bir fikir olduğunu düşünüyorum.
Manngo

2

Sadece yap:

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

1
dahice bir fikir gibi görünmek
pery mimon

0

Bu yazıya bir göz atabilirsiniz . Kod şöyle görünebilir:

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

IE10'da mükemmel şekilde çalışan Larry'nin senaryosu sayesinde, bunu kullandım:

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

0

Larry's'den uzanıyor. Tüm bloğu ve çocuk düğümlerini yinelemeli olarak aramasını sağladım.
Komut dosyası artık src parametresiyle belirtilen harici komut dosyalarını da çağıracaktır. Komut dosyaları, yerleştirilmek yerine başa eklenir ve bulundukları sıraya göre yerleştirilir. Bu nedenle, özellikle sipariş komut dosyaları korunur. Ve her komut dosyası, tarayıcının ilk DOM yüklemesini işleme şekline benzer şekilde eşzamanlı olarak yürütülür. Dolayısıyla, bir CDN'den jQuery'yi çağıran ve sonraki komut dosyası düğümü jQuery'yi kullanan bir komut dosyası bloğunuz varsa ... Sorun yok! Oh ve ben eklenen komut dosyalarını, bu komut dosyası tarafından eklenenleri bulabilmeniz için etiket parametresinde belirlediğinize göre serileştirilmiş bir kimlik ile etiketledik.

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

Bunu deneyin, benim için Chrome, Safari ve Firefox'ta çalışıyor:

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

Yine de dikkat edilmesi gereken bir nokta, aşağıdaki div iç içe betiğin ÇALIŞMAYACAĞIDIR:

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

Bir komut dosyasının çalışması için bir düğüm olarak yaratılması ve ardından alt öğe olarak eklenmesi gerekir. Daha önce enjekte edilen bir div'in içine bir komut dosyası bile ekleyebilirsiniz ve çalışacaktır (daha önce reklam sunucusu kodunu çalıştırmaya çalışırken karşılaştım):

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

Lambder'ın cevabını genişletmek

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

Komut dosyanızı oluşturmak ve yüklemek için base64 görüntüsünü kullanabilirsiniz

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

Ya da eğer varsa Iframeonu kullanabilirsin

<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

Benzer bir şeye ihtiyacım vardı, ancak komut dosyam öğeleri oluşturmak / hedeflemek için komut dosyam DOM'daki komut dosyası etiketinin konumunu hedeflediğinden, komut dosyasının orijinal komut dosyasıyla aynı noktada kalması veya yeniden oluşturulması gerekiyordu. Ayrıca komut dosyasını, birden fazla alt düzeydeyse de çalıştığından emin olmak için yinelemeli yaptım.

NOT: constBurada kullanıyorum, daha eski bir tarayıcınız varsa, sadece kullanın 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

Bu yeni yardımcı işlevi TypeScript'te yaptım, belki birisi takdir edecek. Tür bildirimini komut dosyası parametresinden kaldırırsanız, bu yalnızca düz JS olacaktır.

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

Eval () işlevini deneyin.

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

Bu, geliştirmekte olduğum bir projeden gerçek bir örnek. Bu gönderi sayesinde


-1

İşte son projedeki çözümüm.

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.