为什么通过 DOMParser 创建的脚本元素不执行?
Why script elements created through DOMParser do not execute?
我正在Ajax中加载HTML,用DOMParser
解析它,并将文档正文的所有childNodes
放入一个文档片段中。
当我将片段添加到当前文档的正文中时,<script>
标签没有被执行。
我四处摸索,发现如果我用新的动态创建的脚本标签替换它们,它们就会正确执行。
我想知道为什么?
例如
var html = "Some html with a script <script>alert('test');</script>";
var frag = parsePartialHtml(html);
fixScriptsSoTheyAreExecuted(frag);
document.body.appendChild(frag);
function fixScriptsSoTheyAreExecuted(el) {
var scripts = el.querySelectorAll('script'),
script, fixedScript, i, len;
for (i = 0, len = scripts.length; i < len; i++) {
script = scripts[i];
fixedScript = document.createElement('script');
fixedScript.type = script.type;
if (script.innerHTML) fixedScript.innerHTML = script.innerHTML;
else fixedScript.src = script.src;
fixedScript.async = false;
script.parentNode.replaceChild(fixedScript, script);
}
}
function parsePartialHtml(html) {
var doc = new DOMParser().parseFromString(html, 'text/html'),
frag = document.createDocumentFragment(),
childNodes = doc.body.childNodes;
while (childNodes.length) frag.appendChild(childNodes[0]);
return frag;
}
不调用 fixScriptsSoTheyAreExecuted
,什么都不会执行。
我发现很难理解的另一点是,如果我尝试简单地克隆现有脚本节点以使用 cloneNode
创建新脚本节点,它不起作用,这表明脚本标签最初由 DOMParser
创建的带有阻止它们被执行的状态。
这在 DOM Parsing and Serialization 规范中有解释:
parseFromString
The parseFromString(str, type)
method must run these steps,
depending on type:
"text/html"
Parse str
with an HTML parser
, and return the newly created document.
The scripting flag must be set to "disabled".
Note
script
elements get marked unexecutable and the contents of
noscript
get parsed as markup.
我正在Ajax中加载HTML,用DOMParser
解析它,并将文档正文的所有childNodes
放入一个文档片段中。
当我将片段添加到当前文档的正文中时,<script>
标签没有被执行。
我四处摸索,发现如果我用新的动态创建的脚本标签替换它们,它们就会正确执行。
我想知道为什么?
例如
var html = "Some html with a script <script>alert('test');</script>";
var frag = parsePartialHtml(html);
fixScriptsSoTheyAreExecuted(frag);
document.body.appendChild(frag);
function fixScriptsSoTheyAreExecuted(el) {
var scripts = el.querySelectorAll('script'),
script, fixedScript, i, len;
for (i = 0, len = scripts.length; i < len; i++) {
script = scripts[i];
fixedScript = document.createElement('script');
fixedScript.type = script.type;
if (script.innerHTML) fixedScript.innerHTML = script.innerHTML;
else fixedScript.src = script.src;
fixedScript.async = false;
script.parentNode.replaceChild(fixedScript, script);
}
}
function parsePartialHtml(html) {
var doc = new DOMParser().parseFromString(html, 'text/html'),
frag = document.createDocumentFragment(),
childNodes = doc.body.childNodes;
while (childNodes.length) frag.appendChild(childNodes[0]);
return frag;
}
不调用 fixScriptsSoTheyAreExecuted
,什么都不会执行。
我发现很难理解的另一点是,如果我尝试简单地克隆现有脚本节点以使用 cloneNode
创建新脚本节点,它不起作用,这表明脚本标签最初由 DOMParser
创建的带有阻止它们被执行的状态。
这在 DOM Parsing and Serialization 规范中有解释:
parseFromString
The
parseFromString(str, type)
method must run these steps, depending on type:
"text/html"
Parse
str
with anHTML parser
, and return the newly created document.The scripting flag must be set to "disabled".
Note
script
elements get marked unexecutable and the contents ofnoscript
get parsed as markup.