">文档:<amp-iframe> - amp.dev - AMP 框架
AMP

amp-iframe

实验性
Bento

描述

显示一个 iframe。

 

必需脚本

<script async custom-element="amp-iframe" src="https://cdn.ampproject.org/v0/amp-iframe-1.0.js"></script>

用法

显示一个 AMP 有效 iframe。amp-iframe 与普通 iframe 有几个重要的区别,这些区别旨在使其更安全,并避免 AMP 文件被单个 iframe 占据

  • amp-iframe 可能不会显示在文档顶部附近(使用 placeholder 的 iframe 除外,如下所述所示)。无论滚动到顶部时 iframe 距离顶部 600 像素还是不在视口的前 75%,以较小者为准,iframe 都必须满足此条件。
  • 默认情况下,amp-iframe 处于沙盒状态(请参阅详细信息)。
  • amp-iframe 只能通过 HTTPS、数据 URI 或 srcdoc 属性请求资源。
  • amp-iframe 不能与容器同源,除非它们在 sandbox 属性中不允许 allow-same-origin。有关 iframe 允许来源的更多详细信息,请参阅"Iframe 来源策略"文档。
<amp-iframe
  width="200"
  height="100"
  sandbox="allow-scripts allow-same-origin"
  layout="responsive"
  src="https://www.google.com/maps/embed/v1/place?key=AIzaSyAyAS599A2GGPKTmtNr9CptD61LE4gN6oQ&q=iceland"
>
</amp-iframe>

从 0.1 迁移

0.1 不同,amp-iframe 的实验性 1.0 版本已弃用 frameborder 属性。使用 CSS border 属性控制 <amp-iframe> 边框。

使用现有的 AMP 组件,而不是 amp-iframe

amp-iframe 组件应被视为一种备用方案,如果 AMP 中无法通过其他方式实现所需的用户体验,即对于用例还没有现有的 AMP 组件。这是因为针对特定用例定制的 AMP 组件有很多好处,例如

  • 更好的资源管理和性能
  • 自定义组件在某些情况下可以提供内置占位符图像。这意味着在视频加载之前获取正确的视频缩略图,并减少手动添加占位符的编码工作。
  • 内置调整大小。这意味着大小不可预测的 iframe 内容对用户而言更像是页面原生内容,而不是可滚动框架中的内容
  • 可以内置其他附加功能(例如,视频播放器的自动播放)

amp-iframe 用于广告

不得amp-iframe 用于展示广告的主要目的。将 amp-iframe 用于展示视频的目的是可以的,其中部分视频是广告。此 AMP 政策可能会通过不渲染相应 iframe 来强制执行。

广告用例应改用 amp-ad

此政策的原因在于

  • amp-iframe 强制执行沙箱,沙箱也应用于子 iframe。这意味着即使广告本身似乎有效,着陆页也可能会损坏。
  • amp-iframe 不提供任何将配置传递给 iframe 的机制。
  • amp-iframe 没有完全由 iframe 控制的调整大小机制。
  • amp-iframe 可能无法获得可视性信息。

在有效的 AMP 文档之外独立使用

Bento 允许你在非 AMP 页面中使用 AMP 组件,而无需完全符合 AMP 规范。你可以使用这些组件并将其放置在不支持 AMP 的框架和 CMS 中的实现中。在我们的指南 在非 AMP 页面中使用 AMP 组件 中阅读更多信息。

要查找 amp-iframe 的独立版本,请参阅 bento-iframe

带有占位符的 iframe

amp-iframe 具有 placeholder 元素时,可以使 amp-iframe 出现在文档顶部,如下面的示例所示。

  • amp-iframe 必须包含一个具有 placeholder 属性的元素(例如 amp-img 元素),该元素将在 iframe 准备好显示之前作为占位符呈现。
  • 可以通过监听 iframe 的 onload 或 iframe 文档发送的 embed-ready postMessage 来了解 iframe 的准备情况,以先到者为准。

以下示例显示了一个带占位符的 iframe

<amp-iframe
  width="300"
  height="300"
  layout="responsive"
  sandbox="allow-scripts allow-same-origin"
  src="https://foo.com/iframe"
>
  <amp-img layout="fill" src="https://foo.com/foo.png" placeholder></amp-img>
</amp-iframe>

以下示例显示了一个带有嵌入就绪请求的 iframe

window.parent.postMessage(
  {
    sentinel: 'amp',
    type: 'embed-ready',
  },
  '*'
);

Iframe 调整大小

amp-iframe 必须具有静态布局,就像任何其他 AMP 元素一样。但是,可以在运行时调整 amp-iframe 的大小。为此

  1. amp-iframe 必须使用 resizable 属性进行定义。
  2. amp-iframe 必须具有 overflow 子元素。此元素通常可以是 div。但是,如果 amp-iframep 元素的子元素,则建议使用 spanbutton(以消除由 p 元素的 短语内容 引起的问题)。
  3. amp-iframe 必须设置 allow-same-origin 沙盒属性。
  4. iframe 文档必须将 embed-size 请求作为窗口消息发送。
  5. 如果请求高度小于某个阈值(100px),则 embed-size 请求将被拒绝。

请注意,resizablescrolling 的值覆盖为 no

以下示例显示了具有 overflow 元素的 amp-iframe

<amp-iframe
  width="300"
  height="300"
  layout="responsive"
  sandbox="allow-scripts allow-same-origin"
  resizable
  src="https://foo.com/iframe"
>
  <div overflow tabindex="0" role="button" aria-label="Read more">
    Read more!
  </div>
</amp-iframe>

以下示例显示了 iframe 调整大小请求

window.parent.postMessage(
  {
    sentinel: 'amp',
    type: 'embed-size',
    height: document.body.scrollHeight,
  },
  '*'
);

收到此消息后,AMP 运行时会尝试尽快满足请求,但会考虑读者当前正在阅读的位置、滚动是否正在进行以及任何其他 UX 或性能因素。如果运行时无法满足调整大小的请求,则 amp-iframe 将显示一个 overflow 元素。单击 overflow 元素将立即调整 amp-iframe 的大小,因为它是由用户操作触发的。

以下是一些影响调整大小执行速度的因素

  • 调整大小是否由用户操作触发。
  • 是否为当前活动的 iframe 请求调整大小。
  • 是否为视口下方或视口上方的 iframe 请求调整大小。

Iframe 可见性

Iframe 可以向其父级发送 send-intersections 消息,以开始接收 iframe 与父视口的交集的 IntersectionObserver 样式 更改记录

在以下示例中,我们假设脚本位于创建的 iframe 中,其中 window.parent 是顶级窗口。如果脚本位于嵌套 iframe 中,请将 window.parent 更改为顶级 AMP 窗口。

以下示例显示了 iframe send-intersections 请求

window.parent.postMessage(
  {
    sentinel: 'amp',
    type: 'send-intersections',
  },
  '*'
);

iframe 可以监听来自父窗口的 intersection 消息以接收交集数据。

以下示例显示了 iframe send-intersections 请求

function isAmpMessage(event, type) {
  return (
    event.source == window.parent &&
    event.origin != window.location.origin &&
    event.data &&
    event.data.sentinel == 'amp' &&
    event.data.type == type
  );
}
window.addEventListener('message', function (event) {
  if (!isAmpMessage(event, 'intersection')) {
    return;
  }
  event.data.changes.forEach(function (change) {
    console.log(change);
  });
});

当交叉比率在阈值 [0、0.05、0.1、... 0.9、0.95、1] 之间变化时,父级会以 IntersectionObserver 条目的格式将交叉消息发送给 iframe。

属性

src

src 属性的行为与标准 iframe 主要类似,但有一个例外:#amp=1 片段会添加到 URL 中,以便源文档知道它们嵌入在 AMP 上下文中。仅当 src 指定的 URL 还没有片段时,才会添加此片段。

srcdocframeborderallowfullscreenallowpaymentrequestallowtransparencyreferrerpolicy

这些属性的行为都应该与它们在标准 iframe 中的行为相同。

如果未指定 frameborder,则默认情况下,它将设置为 0

sandbox

amp-iframe 创建的 iframe 始终在其上定义了 sandbox 属性。默认情况下,该值为“”,这意味着它们是“最大沙盒”。通过设置 sandbox 值,可以将 iframe 设置为沙盒较少。浏览器支持的所有值都是允许的。例如,设置 sandbox="allow-scripts" 允许 iframe 运行 JavaScript,或者 sandbox="allow-scripts allow-same-origin" 允许 iframe 运行 JavaScript、进行非 CORS XHR 以及读/写 cookie。

如果你要对未专门针对沙盒创建的文档进行 iframe,则很可能需要将 allow-scripts allow-same-origin 添加到 sandbox 属性,并且可能需要允许其他功能。

还要注意,沙盒适用于从沙盒 iframe 打开的所有窗口。这包括通过具有 target=_blank 的链接创建的新窗口(添加 allow-popups 以允许这样做)。将 allow-popups-to-escape-sandbox 添加到 sandbox 属性,会使这些新窗口的行为类似于非沙盒新窗口。这很可能就是你想要和期望的。不幸的是,截至本文撰写之时,allow-popups-to-escape-sandbox 已得到 Chrome、Firefox、Safari 和 Opera 的支持,但 Edge 不支持。

有关 sandbox 属性的更多详细信息,请参阅 MDN 上的文档

通用属性

amp-iframe 包括扩展到 AMP 组件的 通用属性

分析

我们强烈建议将 amp-analytics 用于分析目的,因为它是一个更加强大、完整且高效的解决方案,可以针对各种分析供应商进行配置。

AMP 每个页面只允许一个用于分析和跟踪目的的 iframe。为了节省资源,这些 iframe 将在加载后 5 秒从 DOM 中删除,这应该足够完成需要完成的任何工作。

如果 iframe 似乎没有为用户提供直接目的,例如不可见或较小,则它们会被识别为跟踪/分析 iframe。

验证

请参阅 AMP 验证器规范中的 amp-iframe 规则

需要更多帮助?

您已经阅读了本文档十几次,但它并没有真正涵盖您所有的问题?也许其他人也有同感:在 Stack Overflow 上联系他们。

转到 Stack Overflow
发现了一个 bug 或缺少某个功能?

AMP 项目强烈鼓励您参与和贡献!我们希望您成为我们开源社区的持续参与者,但我们也欢迎您对您特别热衷的问题进行一次性贡献。

转到 GitHub