AMP

重要提示:此文档不适用于您当前选择的格式 电子邮件

amp-iframe

 
您现在可以使用此组件在有效的 AMP 文档之外使用 此组件的 Bento 版本。 在 Bento 指南中了解更多信息。

描述

显示一个 iframe。

 

必需的脚本

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

用法

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

  • amp-iframe 不得出现在文档顶部附近(除非是使用 placeholder 的 iframe,如下文所述)。 iframe 必须距离顶部 600 像素或不在滚动到顶部时视口的第一个 75% 内,以较小者为准。
  • 默认情况下,amp-iframe 是沙盒化的(请参阅详细信息)。
  • amp-iframe 只能通过 HTTPS、来自数据 URI 或通过 srcdoc 属性请求资源。
  • 除非它们不允许在 sandbox 属性中使用 allow-same-origin,否则 amp-iframe 不得与容器具有相同的来源。 有关 iframe 允许的来源的更多详细信息,请参阅“Iframe 来源策略”文档。
<amp-iframe
  width="200"
  height="100"
  sandbox="allow-scripts allow-same-origin"
  layout="responsive"
  frameborder="0"
  src="https://www.google.com/maps/embed/v1/place?key=AIzaSyAyAS599A2GGPKTmtNr9CptD61LE4gN6oQ&q=iceland"
>
</amp-iframe>

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

如果通过 AMP 中的其他方式无法实现所需的用户体验,即对于该用例没有现有的 AMP 组件,则应将 amp-iframe 组件视为回退。 这是因为使用为特定用例量身定制的 AMP 组件有很多好处,例如

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

amp-iframe 用于广告的用法

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

广告用例应改为使用 amp-ad

此策略的原因是

  • amp-iframe 强制执行沙盒化,沙盒也应用于子 iframe。 这意味着即使广告本身看起来可以正常工作,着陆页也可能被破坏。
  • amp-iframe 不提供任何将配置传递给 iframe 的机制。
  • amp-iframe 没有完全由 iframe 控制的调整大小机制。
  • amp-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>

以下示例显示了带有 embed-ready 请求的 iframe

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

Iframe 调整大小

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

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

请注意,resizable 会将 scrolling 的值覆盖为 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] 的 intersectionRatio 发生变化时,父级会将交叉消息以 IntersectionObserver 条目的格式发送到 iframe。

如果其父页面上存在 CMP,则 iframe 可以发送 send-consent-data 消息以接收同意数据。

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

示例:iframe send-consent-data 请求

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

iframe 可以通过侦听 consent-data 消息来接收同意数据响应。

请注意

  • consent-data 响应将只发送一次,并且在同意状态更改时(例如,当用户决定通过使用帖子提示 UI 拒绝同意时)不会更新 iframe
  • 当省略 data-block-on-consent 时,将使用 default 策略,并且 iframe 将立即加载。 consent-data 响应可能会根据所选策略延迟。 有关更多信息,请参阅 amp-consent

示例:iframe send-consent-data 请求

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, 'consent-data')) {
    return;
  }
  console.log(event.data.consentMetadata);
  console.log(event.data.consentString);
});

属性

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 嵌入一个并非专门为沙盒环境创建的文档,您很可能需要在 sandbox 属性中添加 allow-scripts allow-same-origin,并且可能需要允许其他功能。

另请注意,沙盒适用于从沙盒 iframe 打开的所有窗口。这包括通过带有 target=_blank 的链接创建的新窗口(添加 allow-popups 以允许这种情况发生)。在 sandbox 属性中添加 allow-popups-to-escape-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
发现错误或缺少功能?

AMP 项目强烈鼓励您的参与和贡献!我们希望您能成为我们开源社区的长期参与者,但也欢迎您针对自己特别关注的问题进行一次性贡献。

转到 GitHub