srcdoc可实现轻量沙箱隔离,但必须配sandbox属性并严格控制权限:需补全HTML结构、内联CSS/JS、禁用危险协议,生产环境禁用allow-same-origin,通过postMessage通信确保主页面安全。

能做,但关键不在“怎么写”,而在“怎么隔离”。直接用 iframe + document.write 或 srcdoc 就能跑起来,但用户随便写个 alert(1) 或 document.cookie 不会伤到主页面——这才是真正要解决的问题。
为什么不能直接 innerHTML 到 body 里
新手常犯的错:把用户写的 HTML 字符串拼好后,用 document.getElementById('preview').innerHTML = userHtml 往一个 div 里塞。这看着能显示,但隐患极多:
-
<script></script>标签不会执行(浏览器安全策略阻止动态插入脚本) -
<link rel="stylesheet">和@import会被忽略或加载失败 - 用户写的
document.write、window.onload、console.log全部失效或污染主页面全局环境 - 更严重的是:CSS 里的
body { background: red }会直接改掉你整个编辑器页面的背景
用 iframe + srcdoc 是最简可行方案
srcdoc 是现代浏览器(Chrome 20+、Firefox 19+、Safari 10.1+)原生支持的属性,它让 iframe 渲染一段 HTML 字符串,且天然隔离 DOM、JS 执行域和样式作用域。
实操时注意三点:
立即学习“前端免费学习笔记(深入)”;
- 必须显式设置
iframe的sandbox属性,比如sandbox="allow-scripts allow-same-origin"—— 否则 JS 不会执行,但allow-same-origin有风险,仅用于本地可信环境;生产环境建议去掉它,用postMessage通信 - 拼接最终 HTML 字符串时,要补全标准结构:
<!DOCTYPE html><html><head><meta charset="utf-8"></head><body>${userBody}</body></html>,否则 CSS/JS 可能不生效 - 如果用户写了
<style>或<script>,它们会按顺序在 iframe 内执行,无需额外处理;但要注意:外部引入的<script src="..."></script>在 sandbox 下默认被拦截,需加allow-scripts且确保资源是 HTTPS
绕不开的 XSS 防御细节
你以为用户只能写 HTML?错。只要他能输入,就可能注入 <script>fetch('/api/steal', {credentials:'include'})</script>。哪怕你用了 srcdoc,也挡不住这类攻击。
真正有效的做法不是“过滤标签”,而是控制执行上下文:
- 生产环境务必去掉
allow-same-origin,这样 iframe 内 JS 就无法读取主站 Cookie 或 localStorage - 若需调试能力,用
postMessage单向通信:iframe 内脚本只能发消息给父页,父页再决定是否响应(比如返回 console 日志) - 对用户输入不做 HTML 转义(那会破坏代码),但要在拼入
srcdoc前,用正则剔除危险协议,例如替换掉javascript:、data:text/html、vbscript:等伪协议 - 不要信任任何用户传入的
<iframe src="...">,一律重写为<iframe src="about:blank">并清空其src
最易被忽略的一点:很多人以为 “iframe + sandbox” 就万事大吉,其实 sandbox 默认是禁用所有能力的,漏加 allow-scripts 会导致 JS 完全不执行,而加了又可能留口子——这个平衡点必须根据使用场景手动权衡,没有银弹。



















