Menu

HTML iframe:嵌入网页、视频和地图

<iframe> 元素可以在你的页面中显示另一个网页。学习需要用到的属性(src、title、width、height)、如何嵌入 YouTube 视频和地图、如何让 iframe 自适应、sandbox 如何限制它的能力,以及为什么有些网站拒绝在 iframe 中加载。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

如何使用 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-popupswindow.open 和 target="_blank" 链接
allow-modalsalert()、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 等关键字,只放开嵌入内容需要的功能。

Coddy 编程语言插图

和 Coddy 一起学编程

开始