为啥浏览器不在通过 fetch API 检索的 HTML 片段中运行 <script>? [复制]
Posted
技术标签:
【中文标题】为啥浏览器不在通过 fetch API 检索的 HTML 片段中运行 <script>? [复制]【英文标题】:Why doesn't a browser run a <script> in an HTML fragment retrieved via fetch API? [duplicate]为什么浏览器不在通过 fetch API 检索的 HTML 片段中运行 <script>? [复制] 【发布时间】:2018-09-26 18:38:48 【问题描述】:我正在尝试使用 fetch API 获取 html 片段,然后将其添加到 HTML 页面。虽然这适用于 HTML 内容,但我注意到如果我在片段中放置 <script>
标记,该标记不会被剥离,但也不会被执行。
下面是一个例子。我希望alert
会触发,但它不会触发,即使脚本标签出现在页面上。
我的问题是 (1) 为什么 <script>
没有得到评估,以及 (2) 有没有办法让它评估?
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Index</title>
</head>
<body>
<script src="main.js"></script>
</body>
</html>
fragment.html
<h1>Hello</h1>
<p>It works</p>
<script>
alert('hello') // doesn't work, but script still appears on page
</script>
main.js
fetch('fragment.html').then((res)=>
return res.text()
).then((data)=>
var div = document.createElement('div')
div.innerHTML = data
document.body.appendChild(div)
)
【问题讨论】:
因为脚本只在加载页面时执行。 您可以使用$(elm).html(str)
而不是elm.innerHTML=str;
来运行此类内容。
【参考方案1】:
因为这就是HTML spec dictates:
使用innerHTML 插入的脚本元素在被插入时不会执行 插入。
我在这里做一些假设,但可能是为了引入一层安全性,这样你就不会意外引入 XSS 或code injection。
如果你想让脚本运行,获取它们的内容,创建一个特定的<script>
元素,将脚本的主体设置为内容,然后将其插入到 DOM 中:
const script = document.createElement("script"),
text = document.createTextNode("console.log('foo')");
script.appendChild(text);
document.body.appendChild(script);
【讨论】:
以上是关于为啥浏览器不在通过 fetch API 检索的 HTML 片段中运行 <script>? [复制]的主要内容,如果未能解决你的问题,请参考以下文章