簡體   English   中英

DOMParser 附加<script> tags to <head>/<body> but not executing

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

我試圖通過 DOMParser 將一個字符串解析為一個完整的 HTML 文檔,然后用處理過的節點覆蓋當前頁面。 該字符串包含完整的標記,包括<!doctype><html><head><body>節點。

// parse the string into a DOMDocument element:
var parser = new DOMParser();
var doc = parser.parseFromString(data, 'text/html');

// set the parsed head/body innerHTML contents into the current page's innerHTML
document.getElementsByTagName('head')[0].innerHTML = doc.getElementsByTagName('head')[0].innerHTML;
document.getElementsByTagName('body')[0].innerHTML = doc.getElementsByTagName('body')[0].innerHTML;

這是因為它成功地獲取了已解析的 HTML 節點並將它們呈現在頁面上; 但是,解析字符串內的<head><body>節點中存在的任何<script>標記都無法執行 =[。 直接使用html標簽(與head / body相對)進行測試會產生相同的結果。

我也嘗試過使用.appendChild()而不是.innerHTML() ,但沒有改變:

var elementHtml = document.getElementsByTagName('html')[0];

// remove the existing head/body nodes from the page
while (elementHtml.firstChild) elementHtml.removeChild(elementHtml.firstChild);

// append the parsed head/body tags to the existing html tag
elementHtml.appendChild(doc.getElementsByTagName('head')[0]);
elementHtml.appendChild(doc.getElementsByTagName('body')[0]);

有誰知道將字符串轉換為完整的 HTML 頁面執行其中包含的 javascript 的方法嗎?

如果有替代 DOMParser 的方法可以提供相同的結果(例如覆蓋整個文檔),請隨時推薦它/它們 =]

注意
我使用它而不是更簡單的document.write(data)替代方案的原因是因為我需要在 SSL 下的 IE 中的postMessage()回調中使用它; document.write()在 IE 中訪問 SSL 頁面時在回調事件中被阻止,例如發布消息 =[

你應該使用:

const sHtml = '<script>window.alert("Hello!")</script>';
const frag = document.createRange().createContextualFragment(sHtml)
document.body.appendChild( frag );

使用問題中描述的DOMParser()將正確設置頁面的<head><body>內容,但需要更多的工作來執行任何現有的<script>標簽。

這里的基本方法是在設置內容后拉出頁面中所有<script>標簽的列表,迭代該列表並使用現有內容動態創建一個新的<script>標簽,然后添加新的一頁。

例子:

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

這是 jQuery 1.8.3 的工作演示(鏈接到 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"));
});

因此,我使用了$.parseXML()函數,如果您的 HTML 也是有效的 XML,那么您顯然只能使用該函數。 不幸的是,相同的代碼不適用於 jQuery 1.9.1(不再找到<script>標簽): http : //jsfiddle.net/6cECR/8/也許它是一個錯誤(或一個安全特性......)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM