重要提示:此文档不适用于您当前选择的格式 stories!
amp-iframe
描述
显示 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、data-URI 或通过srcdoc
属性请求资源。amp-iframe
不得与容器同源,除非它们不允许在sandbox
属性中使用allow-same-origin
。有关 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>
以下示例显示了带有嵌入就绪请求的 iframe
window.parent.postMessage( { sentinel: 'amp', type: 'embed-ready', }, '*' );
Iframe 调整大小
与任何其他 AMP 元素一样,amp-iframe
必须定义静态布局。但是,可以在运行时调整 amp-iframe
的大小。为此
- 必须使用
resizable
属性定义amp-iframe
。 amp-iframe
必须具有overflow
子元素。此元素通常可以是div
。但是,如果amp-iframe
是p
元素的子元素,则建议使用span
或button
(以消除由p
元素的短语内容引起的问题)。amp-iframe
必须设置allow-same-origin
sandbox 属性。- iframe 文档必须以窗口消息的形式发送
embed-size
请求。 - 如果请求高度小于某个阈值(100 像素),则将拒绝
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。
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 还没有片段时,才会添加此片段。
srcdoc
, frameborder
, allowfullscreen
, allowpaymentrequest
, allowtransparency
和 referrerpolicy
这些属性的行为应该都与标准 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 发现错误或缺少功能?AMP 项目强烈鼓励您的参与和贡献!我们希望您能成为我们开源社区的持续参与者,但我们也欢迎您对您特别感兴趣的问题做出一次性贡献。
前往 GitHub