
当一个内联 在另一个脚本执行过程中被动态插入(如通过 document.write),浏览器会立即中断当前脚本流,同步执行新脚本,这正是 WHATWG 规范中“even if other scripts are already executing”的真实场景。
当一个内联 `<script>` 在另一个脚本执行过程中被动态插入(如通过 `document.write`),浏览器会**立即中断当前脚本流,同步执行新脚本**,这正是 whatwg 规范中“even if other scripts are already executing”的真实场景。</script>
在 HTML 解析与执行模型中,脚本的执行并非总是线性排队的。WHATWG HTML 规范在 “Prepare the script element” 算法中明确指出:
Otherwise, immediately execute the script element
el, even if other scripts are already executing.
这一行为看似违反直觉——JavaScript 是单线程的,何来“另一个脚本正在执行”?关键在于:此处的“正在执行”指的是解析器正处于脚本执行上下文中(例如正运行 <script></script> 内容),而新插入的脚本会触发同步、阻塞式的即时求值,而非加入事件队列或等待空闲。
✅ 典型触发条件(三者必须同时满足):
- 脚本为内联脚本(无
src属性); - 脚本非模块类型(即
type="module"不适用,模块始终异步且受加载依赖约束); - 脚本是在已有脚本执行期间动态注入的,最经典方式是
document.write()(仅在文档仍在解析时有效)。
? 实例演示
以下代码清晰复现该机制:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
立即学习“前端免费学习笔记(深入)”;
<script>
console.log("① before");
document.write(`<script>
console.log("② nested — executed IMMEDIATELY");
<\/script>`);
console.log("③ after");
</script>控制台输出顺序为:
① before ② nested — executed IMMEDIATELY ③ after
⚠️ 注意:② 并非延迟执行,也不是微任务/宏任务调度结果;它是在 document.write 写入后,HTML 解析器当场暂停当前 <script></script> 的 JS 执行栈,回退到解析阶段,识别新 <script></script> 标签,并立刻编译+执行其内容——整个过程同步阻塞,原脚本的后续语句(console.log("③ after"))需等待嵌套脚本完全返回后才继续。
⚠️ 重要限制与注意事项
-
document.write仅在文档初始解析阶段有效;若在DOMContentLoaded或load事件后调用,将自动调用document.open()清空整个文档,造成严重副作用,现代开发中应严格避免。 -
innerHTML += '<script>...'</script>或insertAdjacentHTML不会触发此行为:它们仅插入 DOM 节点,但不会让浏览器“重新解析并立即执行”其中的<script></script>(除非显式调用eval或创建并appendChild动态 script 元素——此时执行时机由用户控制,非规范定义的“immediate execution”)。 - 此机制是 HTML 解析器与 JS 引擎深度耦合的历史产物,属于解析时(parser-inserted)脚本的特有行为,与
setTimeout、Promise.then、MutationObserver等运行时调度无关。 - 在
async/defer脚本、模块脚本或fetch()+eval()场景中,均不适用该规则。
? 总结
所谓“一个脚本中断另一个脚本”,本质是 HTML 解析器在脚本执行中途被 document.write 注入新脚本标签,从而触发规范定义的同步重入执行路径。这是少数几个能让 JS 执行流出现“栈内嵌套执行”的原生机制之一,体现了 HTML 解析与脚本执行的紧密协同。尽管该模式已不推荐用于现代应用(因其破坏可预测性、阻碍流式渲染、与 CSP 冲突),但深入理解它,对排查老项目异常执行顺序、分析 XSS 利用链(如 document.write 注入触发 DOM 型 XSS)以及掌握浏览器底层工作原理仍具关键价值。


















