DOMParser将<script>标记附加到<head> / <body>但不执行</script>

时间:2014-04-08 18:57:26

标签: javascript domparser

我试图通过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节点并在页面上呈现它们;但是,解析后的字符串中<script><head>个节点中存在的任何<body>标记都无法执行= [。直接使用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()回调中使用它;在IE = [

]中访问SSL页面时,回调事件(如发布消息)中会阻止document.write()

3 个答案:

答案 0 :(得分:7)

如问题中所述,使用DOMParser()会正确设置页面的<head><body>内容,但需要做更多工作才能将任何现有的<script>代码添加到执行。

这里的基本方法是在设置内容后拉出页面中所有<script>标记的列表,迭代该列表并动态创建 new {{1} }标记现有内容的内容,然后将新的内容添加到页面。

示例:

<script>

答案 1 :(得分:0)

以下是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"));
});

因此,如果你的HTML也是有效的XML,我使用了你只能使用的函数$.parseXML()。不幸的是,相同的代码不能与jQuery 1.9.1一起使用(<script>标签不再存在):http://jsfiddle.net/6cECR/8/也许它是一个bug(或安全产品......)

答案 2 :(得分:0)

您应该使用:

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