为何通过jQuery从字符串解析的script标签插入DOM后不加载资源
问题涉及的两种实现代码
不生效的实现
<html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> </head> <body> <script> let sLoadThis = `<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/underscore@latest/underscore-umd-min.js"></script>`; let oScript = $(sLoadThis).get(0); document.head.appendChild(oScript); </script> </body> </html>
可正常生效的实现
<html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> </head> <body> <script> let sLoadThis = `<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/underscore@latest/underscore-umd-min.js"></script>`; let oScript = $(sLoadThis).get(0); var vanillaScript = document.createElement('script') vanillaScript.type = 'text/javascript' vanillaScript.src = oScript.src document.head.appendChild(vanillaScript) </script> </body> </html>
第一种实现不生效的核心原因
- jQuery内置解析逻辑的拦截
jQuery处理包含script标签的HTML字符串时,为了防范XSS安全风险,内部调用的parseHTML方法默认会对解析生成的script标签做特殊标记,禁止其自动加载执行,哪怕后续将节点插入DOM树,也不会触发浏览器的资源加载流程。 - 浏览器的动态script执行规则限制
浏览器本身有安全限制:所有通过innerHTML、DOM片段解析生成的script标签,插入DOM后都不会触发资源加载和代码执行;只有通过document.createElement('script')显式创建的script标签,插入DOM时才会自动触发src对应的资源加载和代码执行。
第二种实现中重新用原生方法创建了script标签,符合浏览器的触发规则,因此可以正常加载。
补充说明
如果需要直接使用jQuery解析的script节点,可以调整写法开启script加载权限:
let oScript = $.parseHTML(sLoadThis, document, true)[0]; document.head.appendChild(oScript);
第三个参数keepScripts设为true后,jQuery就不会拦截script的加载执行,注意仅在你完全信任HTML字符串来源的情况下使用,避免XSS攻击。
内容的提问来源于stack exchange,提问作者Pieter
相关产品推荐
相关产品推荐

