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` 不得靠近文件頂端顯示(除非 iframe 使用如下方 說明的 `placeholder`)。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 準備就緒的狀態可以透過監聽 iframe 的 `onload` 或 iframe 文件傳送的 `embed-ready` `postMessage` 來得知,以先到者為準。
下列範例顯示具有預留位置的 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-iframe` 必須定義靜態版面配置,如同任何其他 AMP 元素一樣。不過,可以在執行階段調整 `amp-iframe` 的大小。若要這麼做:
- `amp-iframe` 必須使用 `resizable` 屬性定義。
- `amp-iframe` 必須具有 `overflow` 子元素。此元素通常可以是 `div`。不過,如果 `amp-iframe` 是 `p` 元素的子元素,建議使用 `span` 或 `button` (以消除 `p` 元素 詞組內容 造成的 issue)。
- `amp-iframe` 必須設定 `allow-same-origin` 沙箱屬性。
- 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 執行階段會盡快嘗試滿足要求,但會考量讀取器目前的閱讀位置、捲動是否正在進行中,以及任何其他使用者體驗或效能因素。如果執行階段無法滿足調整大小要求,`amp-iframe` 將會顯示 `overflow` 元素。按一下 `overflow` 元素會立即調整 `amp-iframe` 的大小,因為它是由使用者動作觸發。
以下是一些會影響調整大小執行速度的因素:
- 調整大小是否由使用者動作觸發。
- 調整大小是否針對目前作用中的 iframe 要求。
- 調整大小是否針對視窗下方或上方的 iframe 要求。
Iframe 可見度
Iframe 可以將 `send-intersections` 訊息傳送給其父項,以開始接收 `IntersectionObserver` 樣式的變更記錄,記錄 iframe 與父項視窗的交集。
在下列範例中,我們假設指令碼位於建立的 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); }); });
交集訊息會由父項以 `IntersectionObserver` 條目的格式傳送至 iframe,每當 intersectionRatio 跨越閾值 [0, 0.05, 0.1, ... 0.9, 0.95, 1] 變更時。
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` 屬性,可讓這些新視窗的行為與非沙箱化新視窗的行為相同。這很可能在大多數情況下是您想要且預期的行為。遺憾的是,在撰寫本文時,Chrome、Firefox、Safari 和 Opera 支援 `allow-popups-to-escape-sandbox`,但 Edge 不支援。
如需 `sandbox` 屬性的詳細資訊,請參閱 MDN 上的文件。
通用屬性
`amp-iframe` 包含擴充至 AMP 組件的 通用屬性。
分析
我們強烈建議基於分析目的使用 `amp-analytics`,因為這是一種更強大、完整且有效率的解決方案,可以針對各種分析供應商進行設定。
AMP 每頁只允許一個用於分析和追蹤目的的 iframe。為了節省資源,這些 iframe 會在載入後 5 秒從 DOM 中移除,這應該足以完成任何需要完成的工作。
如果 iframe 看起來沒有直接使用者用途 (例如不可見或很小),則會將其識別為追蹤/分析 iframe。
驗證
請參閱 AMP 驗證器規格中的 `amp-iframe` 規則。
您已經讀過這份文件十幾次,但它仍然沒有涵蓋您的所有問題嗎?也許其他人也有同感:請在 Stack Overflow 上與他們聯絡。
前往 Stack Overflow 發現錯誤或缺少功能?AMP 專案大力鼓勵您的參與和貢獻!我們希望您能成為我們開放原始碼社群的長期參與者,但我們也歡迎針對您特別感興趣的問題提供一次性貢獻。
前往 GitHub