本站教程正文里的每个示例框就是 iframe。下面这个是嵌套两层的结果——你正在看的这个页面本身就在外层 iframe 里。
<iframe src="/tutorials/html/demos/01-first-page.html" title="示例:第一个页面" width="100%" height="320" loading="lazy" sandbox="allow-scripts" referrerpolicy="no-referrer-when-downgrade" ></iframe>
下面这个框真的用了 sandbox="allow-scripts"(不含 allow-same-origin),所以里面的脚本能跑,但读不到外层任何数据:
| 值 | 放开什么 | 什么时候需要 |
|---|---|---|
(空值 sandbox="") | 最严格:脚本不能跑、表单不能提交、不能弹窗、不能跳外层 | 渲染不可信的用户内容 |
allow-scripts | 允许内部 JS | 演示代码必须开 |
allow-forms | 允许内部表单提交 | 表单示例 |
allow-modals | 允许 alert / confirm | 讲解弹窗时 |
allow-popups | 允许 window.open | 少见 |
allow-same-origin | 保留同源身份,能读自己的 localStorage / cookie | 需要存储的示例 |
allow-top-navigation | 允许内部把外层页面跳走 | 基本别开,是钓鱼入口 |
关键陷阱:allow-scripts 与 allow-same-origin 同时给且嵌的是同源文档时,沙箱等于没有——内部脚本可以拿到自己的 window 再爬 parent。这两个同时出现时浏览器控制台会给出警告。
读屏用户可以用「框架列表」在 iframe 之间跳转,title 就是列表里显示的名字。漏了 title 的 iframe 在无障碍审计(Lighthouse / axe)里是确定的错误项。
第三方给的嵌入代码通常写死了 width="560" height="315",手机上会横向溢出。用 aspect-ratio 包一层就能自适应:
<div style="aspect-ratio:16/9;position:relative"> <iframe style="position:absolute;inset:0;width:100%;height:100%;border:0" …></iframe> </div>
src,即「facade」模式)。postMessage,两侧都要校验 event.origin,否则任何页面都能给你发消息。