DOMParser appending [removed] tags to <head>/<body> but not executing

后端 未结 3 1251
傲寒
傲寒 2020-12-14 05:05

I\'m attempting to parse a string into a full HTML document via DOMParser and then overwrite the current page with the processed nodes. The string contains complete markup,

相关标签:
3条回答
  • 2020-12-14 05:31

    You should use:

    const sHtml = '<script>window.alert("Hello!")</script>';
    const frag = document.createRange().createContextualFragment(sHtml)
    document.body.appendChild( frag );
    
    0 讨论(0)
  • 2020-12-14 05:35

    Using DOMParser() as described in the question will correctly set the <head> and <body> contents of the page, but more work is necessary to get any existing <script> tags to execute.

    The basic approach here is to pull a list of all <script> tags in the page after the contents have been set, iterate over that list and dynamically create a new <script> tag with the contents of the existing one and then add the new one to the page.

    Example:

    // create a DOMParser to parse the HTML content
    var parser = new DOMParser();
    var parsedDocument = parser.parseFromString(data, 'text/html');
    
    // set the current page's <html> contents to the newly parsed <html> content
    document.getElementsByTagName('html')[0].innerHTML = parsedDocument.getElementsByTagName('html')[0].innerHTML;
    
    // get a list of all <script> tags in the new page
    var tmpScripts = document.getElementsByTagName('script');
    if (tmpScripts.length > 0) {
        // push all of the document's script tags into an array
        // (to prevent dom manipulation while iterating over dom nodes)
        var scripts = [];
        for (var i = 0; i < tmpScripts.length; i++) {
            scripts.push(tmpScripts[i]);
        }
    
        // iterate over all script tags and create a duplicate tags for each
        for (var i = 0; i < scripts.length; i++) {
            var s = document.createElement('script');
            s.innerHTML = scripts[i].innerHTML;
    
            // add the new node to the page
            scripts[i].parentNode.appendChild(s);
    
            // remove the original (non-executing) node from the page
            scripts[i].parentNode.removeChild(scripts[i]);
        }
    }
    
    0 讨论(0)
  • 2020-12-14 05:45

    Here is a working demo for jQuery 1.8.3 (link to jsFiddle):

    var html = "<html><head><script>alert(42);</" + "script></head><body><h1>Hello World</h1></body></html>";
    
    $(function () {
        html = $($.parseXML(html));
    
        $("head").append(html.find("script"));
        $("body").append(html.find("h1"));
    });
    

    Thereby I used the function $.parseXML() which you only can use obviously, if your HTML is also valid XML. Unfortunately is the same code not working with jQuery 1.9.1 (the <script> tag is not found anymore): http://jsfiddle.net/6cECR/8/ Maybe its a bug (or a security fetaure...)

    0 讨论(0)
提交回复
热议问题