跨域 iframe 无法执行脚本且不可访问 contentdocument,仅同源时可通过 load 事件后动态创建 script 元素或使用 srcdoc 注入并执行脚本;document.write() 因解析时机问题已不推荐。

iframe内容必须同源才能执行脚本
跨域 iframe 的 window.contentDocument 或 window.contentWindow 无法访问,JS 会直接抛出 SecurityError。这是浏览器强制限制,绕不过——哪怕你用 document.write() 或 appendChild() 动态插入,只要 iframe 指向不同源(协议、域名、端口任一不同),后续所有脚本操作都会失败。
如果你控制不了 iframe 源(比如嵌入第三方广告或地图),这条路根本走不通;只有父子页面同源时,下面的操作才真正可行。
同源 iframe 中动态注入并立即执行脚本的正确姿势
不能靠 document.write() 写完再调用,也不能把 <script></script> 标签塞进 iframe 的 innerHTML——那样不会执行。必须显式创建 script 元素并挂载到 iframe 的 document 上。
- 先确保 iframe 已加载完成(监听
load事件,或检查iframe.contentDocument.readyState) - 用
iframe.contentDocument.createElement('script')创建脚本节点 - 设置
script.textContent(不要用innerHTML或src,避免二次请求或解析失败) - 调用
iframe.contentDocument.head.appendChild(script)或body.appendChild
示例:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
const iframe = document.getElementById('myIframe');
iframe.addEventListener('load', () => {
const doc = iframe.contentDocument;
const script = doc.createElement('script');
script.textContent = 'console.log("loaded in iframe", window.location.href);';
doc.head.appendChild(script);
});
用 srcdoc 属性一次性注入 HTML + 脚本(仅限同源且无需服务端)
srcdoc 是最干净的方案:它把整个 HTML 字符串作为 iframe 内容,浏览器会完整解析并执行其中的内联脚本(包括 <script></script> 标签和 onload 等事件处理器),且无需等待 load 事件。
-
srcdoc优先级高于src,设了srcdoc就不会发src请求 - 必须手动写
结构,否则某些浏览器可能不渲染或脚本不执行 - 注意单双引号转义:如果脚本里含双引号,
srcdoc值建议用单引号包裹
示例:
iframe.srcdoc = `
<h1>Injected</h1>
<script>console.log("executed immediately");</script>
`;
为什么 document.write() 在 iframe 里大概率失效
很多人试过 iframe.contentDocument.write(...),但发现脚本没执行——这是因为:document.write() 只在文档正在解析时有效;一旦 iframe 加载完成(readyState === 'complete'),再调用就会先清空整个文档,再写入新内容,但此时新内容不会被重新解析执行脚本(尤其在现代 Chrome/Firefox 中)。
- 即使成功写入,也不触发 DOMContentLoaded,内联脚本常被忽略
-
document.write()是遗留 API,已被规范标记为“不鼓励使用” - 在
srcdoc或动态script元素都可用的前提下,完全没必要碰它
真正麻烦的不是怎么插,而是判断“是否已加载完成”和“是否同源”——这两个条件漏掉一个,后面所有代码都是白写。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










