srcdoc 的核心作用是让 iframe 不发网络请求,直接渲染内联完整 html 字符串;必须包含 doctype、html、head、body 结构,css/js 需内联,无 sandbox 则无安全限制,动态更新会重建上下文,ie 完全不支持。

srcdoc 的核心作用是:让 iframe 不发网络请求,直接渲染一段内联的、完整的 HTML 字符串——它不是“塞个 div 就行”的快捷写法,而是等价于把整个 HTML 文件内容原样写进 iframe 的源码里。
srcdoc 必须包含完整 HTML 文档结构
浏览器把 srcdoc 值当独立 HTML 文件解析,缺 、<code>、 或 都可能渲染失败,尤其 Safari 更严格。
- ✅ 正确示例:
srcdoc="<title>Preview</title> <p>Hello</p>" - ❌ 错误写法:
srcdoc="<div>hello</div>"—— 渲染为空白,控制台无报错 -
<title></title>虽非强制,但缺失时旧版 Safari 可能拒渲染,调试也更难定位 - 未闭合标签(如
<div>hello)会导致后续内容被静默截断,不是警告,是直接丢弃 <h3>srcdoc 里不能用外部资源,CSS/JS 必须内联</h3> <p><code>srcdoc内容不发起任何 HTTP 请求,<script src="xxx.js"></script>和<link href="style.css">完全无效,连同目录下的文件也不会加载。- CSS 必须写在
<style></style>标签中,放在里 - JS 必须写在
<script></script>标签中,推荐放底部,或包裹在DOMContentLoaded回调里 - 不要用
document.write()—— 执行会失败,且不报错 - 内联事件(如
onclick="alert(1)")默认被sandbox禁用,即使开了allow-scripts也不生效,必须改用addEventListener
不配 sandbox 就等于裸奔
srcdoc默认没有安全限制,脚本可执行、表单可提交、window.open()可弹窗、甚至能尝试修改top.location。哪怕内容是你自己拼的,只要混入用户输入(比如 Markdown 预览),XSS 风险就真实存在。-
sandbox=""(空值)不是“最小权限”,而是彻底阻断内容加载,Network 面板显示net::ERR_BLOCKED_BY_RESPONSE,iframe 白屏 - 真正可用的起点是显式声明权限,例如:
sandbox="allow-scripts"或sandbox="allow-scripts allow-forms" - 绝对避免
sandbox="allow-same-origin"—— 它对srcdoc无效(origin 固定为null),但若误加,可能误导你放松其他防护 - 通信只能靠
postMessage,父页需校验event.origin === 'null'
动态更新 srcdoc 会重载整个 iframe 上下文
执行
iframe.srcdoc = newHtml不是“刷新页面”,而是销毁并重建整个浏览上下文:所有定时器、事件监听器、正在执行的函数、console.log输出全部清空,contentWindow指向全新实例。- 高频更新(如每键触发的 Markdown 预览)不适合用
srcdoc,应改用contentDocument.write() + document.close()(但需确保同源且无sandbox限制) - 每次更新都得重新注入全部内联 JS,并靠
postMessage同步状态,无法持久保存变量 - IE(包括 IE11)完全不支持
srcdoc,既不报错也不 fallback,结果就是 iframe 空白 —— 必须同时设src="data:text/html;base64,..."作为降级路径
最易被忽略的一点:你以为在写 HTML 片段,其实你在写一个完整文档;你以为只是换了个属性,其实你已经绕过了所有网络加载和同源策略的默认保护层——
srcdoc的简洁性背后,全是结构、转义、沙箱和上下文生命周期的硬约束。 - CSS 必须写在











