innerHTML动态加载页面中script标签不执行的解决方法
原因说明
通过innerHTML向DOM插入内容时,其中包含的<script>标签不会被浏览器解析执行,这是HTML规范明确的安全限制,目的是降低恶意脚本注入的风险,所有主流浏览器都遵循这个规则。
修复方案
核心逻辑是:HTML内容插入完成后,遍历所有新加入的script标签,手动创建全新的script元素,复制原有标签的属性和内联内容后替换掉原标签,浏览器就会正常执行新创建的脚本。
替换后的完整可运行代码如下:
const fetch = (url, call) => { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { call(xhttp); } }; xhttp.open("GET", url, true); xhttp.send(); } const UpdatePage = page_name => { fetch(`/app/${page_name}`, (data) => { // 先渲染静态DOM内容 App.innerHTML = data.responseText; // 提取所有新插入的script标签 const scriptList = App.querySelectorAll('script'); scriptList.forEach(oldScript => { // 创建全新的script DOM节点 const newScript = document.createElement('script'); // 复制原script上的所有属性,比如src、type、defer等 Array.from(oldScript.attributes).forEach(attr => { newScript.setAttribute(attr.name, attr.value); }); // 复制内联脚本的代码内容 newScript.textContent = oldScript.textContent; // 替换原节点,触发脚本执行 oldScript.replaceWith(newScript); }); }) }
注意点
- 该方案会无条件执行动态加载到的所有脚本,必须确保加载的页面来源完全可信,否则会存在XSS安全风险。
- 如果页面中包含带
src属性的外部脚本,默认会异步加载执行,若需要严格按照脚本在页面中的书写顺序串行执行,可以在创建新script节点时加上newScript.async = false,保证执行顺序符合预期。 - 若动态加载的脚本中使用了
document.write方法,执行时会清空整个当前页面,这类特殊脚本需要单独做兼容处理。
内容的提问来源于stack exchange,提问作者Wraith
相关产品推荐
相关产品推荐

