如何使用 iframe
<iframe> 在你的页面中显示另一个页面。在 src 中给出页面地址,加上描述它的 title,再设置尺寸:
<iframe src="https://example.com/" title="Example site" width="600" height="400"></iframe>
框架会把页面作为一个独立的文档加载,有自己的样式和脚本。本页的示例使用 srcdoc 而不是 src,它把框架的 HTML 直接写在属性里,所以不用加载其他网站也能运行:
外层段落是蓝色加粗的;框架里的段落却不是,尽管页面上有同样的 p 规则。样式永远不会跨越框架边界,两个方向都不会。默认边框和 300×150 的默认尺寸来自浏览器;width 和 height 属性会覆盖这个尺寸。
嵌入 YouTube 视频或地图
视频网站和地图服务会提供现成的 iframe 代码。在 YouTube 上,点击“分享”,然后点击“嵌入”:
<iframe width="560" height="315"
src="https://www.youtube.com/embed/VIDEO_ID"
title="YouTube video player"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen></iframe>
对于 Google 地图,打开地点,点击“分享”,再选择“嵌入地图”,用同样的方式复制 iframe。保留 title(屏幕阅读器进入框架时会朗读它),并用下面的自适应 CSS 替换固定尺寸。allow 属性为框架授予自动播放、全屏等功能,嵌入的页面默认不能使用这些功能。
尺寸、边框和自适应 iframe
复制来的嵌入代码使用固定的像素尺寸,在手机上会溢出。width: 100% 加上 aspect-ratio 让框架填满容器并保持比例,border: 0 去掉默认的 inset 边框:
把 max-width: 480px 改成别的值,框架在任何宽度下都会保持 16:9 的比例。去掉 border: 0 就能看到浏览器的默认边框。旧的 frameborder、scrolling 和 marginheight 属性都已过时;请用 CSS。
sandbox:限制框架的能力
框架和任何页面一样,可以运行脚本、提交表单和打开弹出窗口。sandbox 属性会收回这些能力;空的 sandbox 几乎会阻止一切,每个关键字放开一项。下面两个框架拿到的是同样的 HTML,其中有一小段脚本:
第一个框架保留着占位文字,因为它的脚本根本没有运行(Chrome 的控制台会为此记录一条 “Blocked script execution” 消息)。只要嵌入的内容不完全可信,比如用户编写的 HTML,就使用 sandbox,并且只添加它需要的关键字:
| 关键字 | 允许 |
|---|---|
allow-scripts | 运行 JavaScript |
allow-forms | 提交表单 |
allow-popups | window.open 和 target="_blank" 链接 |
allow-modals | alert()、confirm() 和 prompt() |
allow-same-origin | 把内容视为来自它真实的源(Cookie、存储) |
allow-top-navigation | 让整个标签页离开你的页面 |
对于来自你自己的源的内容,绝不要同时使用 allow-scripts 和 allow-same-origin:否则框架中的脚本可以移除自己的沙箱。
与框架通信:postMessage
外层页面和框架是两个独立的文档。当它们的源不同时,彼此无法访问对方的 DOM,但可以互相发送消息。输入一条消息,把它发送到框架中:
在真实代码中,请传入框架的确切源(例如 'https://maps.example.com')而不是 '*',并在接收方检查 e.origin,确保消息只发给、也只来自你预期的网站。
性能,以及网站拒绝嵌入时
- 懒加载。 给页面下方较远处的框架加上
loading="lazy";浏览器只会在读者滚动到附近时才加载它们。每个 iframe 都是一次完整的页面加载,所以嵌入内容很多的页面不加懒加载就会变慢。 - “拒绝连接”。 很多网站(银行、大多数社交网络、Google 搜索)会发送禁止被嵌入的
X-Frame-Options或frame-ancestors响应头,浏览器会在框架中显示错误。你的页面无法绕过它。请使用该网站的官方嵌入 URL,或者改用链接。 - 无障碍访问。 一定要设置
title。屏幕阅读器靠它来称呼这个框架,一个页面上有好几个没有标题的框架时,用户很难在其中来回移动。
常见错误
- 缺少
title。 屏幕阅读器会把框架朗读为未命名。 - 复制来的嵌入代码使用固定宽度。 把它们换成
width: 100%和aspect-ratio。 - 用 iframe 嵌入普通视频文件。 对于你自己的
.mp4文件,请使用 video 元素;iframe 是用来嵌入页面的。 - 信任框架中的内容。 不是你写的内容,都要加上
sandbox。 - 以为外层 CSS 能设置框架的样式。 要在框架页面内部设置它的样式。
常见问题
HTML 中的 iframe 是什么?
<iframe>(内联框架)是一个在当前页面中显示另一个独立网页的框。它有自己的文档、样式和脚本,所以常用于嵌入视频、地图、广告和代码预览。
怎样用 iframe 嵌入 YouTube 视频?
在 YouTube 上选择“分享”,然后选择“嵌入”,复制代码。它是一个 iframe,src 为 https://www.youtube.com/embed/ 加上视频 id。保留 title 和 allowfullscreen 属性,再用 CSS 的 aspect-ratio: 16 / 9 加 width: 100% 让它自适应。
为什么我的 iframe 显示网站拒绝连接?
该网站发送了 X-Frame-Options 或 Content-Security-Policy: frame-ancestors 响应头,禁止其他网站把它嵌入框架。很多网站这样做是为了防止点击劫持。你无法在自己的页面上绕过它;如果该网站提供官方嵌入 URL,请使用它。
怎样去掉 iframe 的边框?
在 CSS 中设置 border: 0。旧的 frameborder="0" 属性已经过时,尽管很多复制来的嵌入代码里仍然带着它。
怎样让 iframe 自适应?
在 CSS 中给它设置 width: 100% 和 aspect-ratio,例如视频用 aspect-ratio: 16 / 9,并且不要设置固定高度。这样 iframe 会随容器缩放,同时保持比例。
iframe 的 sandbox 属性有什么作用?
空的 sandbox 属性会阻止框架内的脚本、表单提交、弹出窗口等,并把其内容视为来自一个唯一的源。然后你可以用 allow-scripts 或 allow-forms 等关键字,只放开嵌入内容需要的功能。