srcdoc是iframe内联HTML的专用属性,需提供完整合法文档结构(含DOCTYPE、html、head、body),引号须转义,禁外链资源,必须配合sandbox使用,IE不支持且需src降级。

srcdoc 是什么,为什么不用 src
srcdoc 是 iframe 的原生属性,允许直接嵌入 HTML 字符串作为 iframe 内容,绕过跨域限制和网络请求。相比 src 指向外部 URL,它更适合渲染可信的、动态生成的富文本(比如用户编辑后暂存的 HTML 片段),因为内容完全在 JS 控制范围内,不触发额外加载或 CSP 外联拦截。
常见误用是把未转义的富文本直接拼进 srcdoc 字符串——这会导致解析失败或 XSS(哪怕内容看似“可信”)。浏览器对 srcdoc 的解析非常严格:它必须是格式良好的 HTML 片段,且所有引号、<、> 都要实体化。
怎么安全地把富文本塞进 srcdoc
关键不是“拼接”,而是“序列化”。不能直接 iframe.srcdoc = '<div>' + html + '</div>',必须对整个 HTML 字符串做 HTML 实体编码(注意:不是 JSON 编码,也不是 URL 编码)。
-
srcdoc值必须是纯字符串,不含未转义的<、>、"、';否则 iframe 会空白或报错Failed to load resource: net::ERR_ABORTED - 推荐用
DOMPurify.sanitize()先过滤 HTML(防 XSS),再用encodeURIComponent+ 手动替换不行——正确做法是用document.createElement('template')或textarea辅助转义 - 简单可靠方案:
function escapeForSrcdoc(html) { const el = document.createElement('textarea'); el.textContent = html; return el.innerHTML; } iframe.srcdoc = escapeForSrcdoc(dirtyHtml);
沙盒行为受 sandbox 属性严格控制
仅靠 srcdoc 不等于自动沙盒化。iframe 默认仍可执行脚本、提交表单、弹窗等。必须显式设置 sandbox 属性,且不带 allow-scripts、allow-popups 等权限,才算真正隔离。
立即学习“前端免费学习笔记(深入)”;
- 最小安全配置:
<iframe sandbox="allow-same-origin" srcdoc="<h1>Hello</h1>"></iframe>—— 注意allow-same-origin本身有风险,若需 DOM 访问才加,否则应省略 - 如果富文本含图片,需加
allow-images;含 CSS 样式,无需额外权限(内联 style 可用);但javascript:协议链接、onerror等事件处理器会被 sandbox 自动禁用 - Chrome 和 Safari 对空
sandbox(即sandbox="")默认禁用一切能力,Firefox 则要求至少一个 token,这点容易漏测
样式隔离与父页面冲突怎么处理
srcdoc 内容默认无继承样式,但也不意味着完全干净:全局 CSS(如 body { font-size: 14px })不会透入,而 iframe 内的 <style> 或内联 style 会生效。问题常出在富文本自带的 class 名或标签选择器意外匹配父页面规则(比如 .content p 泄露进来)。
- 避免依赖外部样式:富文本中尽量用内联
style,或把必要 CSS 通过<style>标签写进srcdoc字符串里 - 不要指望
scoped——<style scoped>在srcdoc中无效,因为没有 Vue/Svelte 运行时 - 字体、行高、颜色等基础样式建议兜底:
<style>*{margin:0;padding:0;} body{line-height:1.6;font-family:sans-serif;}</style>
真正麻烦的是 script 注入检测和 CSP 兼容性——有些环境会把 srcdoc 当作内联脚本对待,即使没写 <script> 也可能被拦截。这时候得检查控制台是否出现 Refused to execute inline script,并确认 CSP 中 script-src 'unsafe-inline' 是否被错误启用。



















