亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在 iframe 加載后從緩存中讀取它的*原始*源

如何在 iframe 加載后從緩存中讀取它的*原始*源

DIEA 2023-07-14 16:21:52
最通用的描述方式是,我只想在客戶端看到視口的某一部分后僅觸發一個網絡請求,然后以最有效的方式使用它并在 iframe 中顯示它。給定一個 DOM 結構如下:<!DOCTYPE html><html>  <head />  <body>    ...    <iframe loading="lazy" sandbox="" src="http://www.example.com" />    <pre />    ...  </body></html>我想在標簽中向客戶展示上述pre內容的來源iframe。該iframe元素可以承載任意文檔,它可以是文本的或二進制的,所知道的是瀏覽器可以顯示它。iframe 的源 URL 托管在同一源上。我的目標是通過訪問 Chromium“view-source:”URL 或類似的 URL 來顯示人們會看到的內容。訪問.contentWindow或.contentdocument屬性可能是不可能的,因為它完全是沙盒的,但即使我可以,文檔的也outerHTML不夠,并且使用 anXMLSerializer顯然會改變輸出。另外,我相信瀏覽器可以編輯文檔的某些區域,例如不必要的空格或格式。我只是嘗試了以下方法:document.body.querySelector("iframe").addEventListener(    "load",    async ( { currentTarget: { src } } ) => {        const data = await fetch(            src, {                cache: "only-if-cached"            }        );        // ... use data    }, {        passive: true,        once: true    });然而,獲取失敗。該 URL 似乎不在瀏覽器的緩存中,但我不想發起新的網絡請求,有沒有一種有效的方法可以做到這一點?我正在考慮使用 Intersection Observer 作為一種潛在的解決方案,因為它只會導致一個網絡請求,但代碼相當長,而且它似乎無法正常工作(我對觀察者缺乏經驗)。
查看完整描述

1 回答

?
海綿寶寶撒

TA貢獻1809條經驗 獲得超8個贊

事件偵聽器和獲取請求可能會發生一些潛在的情況。其他讀者請注意,截至撰寫本文時(2020 年 11 月),僅 Chrome/Chromium、Edge 和 Opera 支持 iframe 中的延遲加載。

這個答案針對的是還想使用延遲加載來動態加載內容的提問者。如果只關心發出單個網絡請求,則可以通過 fetch 請求并src通過 Blob 或數據 URI 或通過 或使用 Service Workers 設置 iframe 來完成srcdoc(下面將對此進行探討)。

添加事件偵聽器之前可能加載的幀

您可以在聲明框架后將事件偵聽器添加到框架中,如果在評估腳本之前加載框架(如果已緩存,則可能會出現這種情況),這可能會產生問題。

contentWindow通常,您可以通過或屬性查看您的框架是否已加載contentDocument,如果是,則在這些框架上運行初始化代碼,但由于該框架是沙盒的,因此無法訪問這些屬性。相反,您可以做的是提前聲明您的處理程序,然后在創建 iframe 時聲明它:

async function loader(frame) {

? ? console.log(frame.src);

? ? // ...

}

<iframe?src="frame.html"?loading="lazy"?sandbox=""?onload="loader(this)"></iframe>

在獲取請求中使用同源

根據 MDN,only-if-cached只能在mode設置為 時使用same-origin,這在您的情況下應該沒問題,因為您說框架是同源的。獲取請求將類似于:

await?fetch(src,?{?mode:?'same-origin',?cache:?'only-if-cached'?});

結果

main.html

<!doctype html>

<html>

? <head>

? ? <meta charset="utf-8" />

? ? <style>

? ? ? .spacer {

? ? ? ? height: 200vh;

? ? ? ? background: lightgray;

? ? ? ? text-align: center;

? ? ? }

? ? </style>

? ? <script>

? ? ? async function loader(frame) {

? ? ? ? var sourceCodeElementId = frame.dataset.code;

? ? ? ? var sourceCodeElement = document.getElementById(sourceCodeElementId);

? ? ? ? var response = await fetch(frame.src, {

? ? ? ? ? mode: 'same-origin',

? ? ? ? ? cache: 'only-if-cached'

? ? ? ? });

? ? ? ? if (response.status === 504) {

? ? ? ? ? // if it didn't load via cache, just get it normally

? ? ? ? ? response = await fetch(frame.src);

? ? ? ? }

? ? ? ? var text = await response.text();

? ? ? ? sourceCodeElement.textContent = text;

? ? ? }

? ? </script>

? </head>

? <body>

? ? <div class="spacer">Scroll Down</div>

? ? <iframe src="frame.html"

? ? ? ? loading="lazy"

? ? ? ? data-code="frame-source-code"

? ? ? ? sandbox=""

? ? ? ? onload="loader(this)">

? ? </iframe>

? ? <pre id="frame-source-code"></pre>

? </body>

</html>

樣本frame.html


<!doctype html>

<html>

Frame

</html>

可選/替代地使用 Service Worker

如果問題是圍繞網絡請求,您可以使用Service Workers,作為上述修復的替代方案或補充。讓它們啟動并運行需要一些工作,但它們可以讓您更好地控制網絡請求。緩存文件是一個常見的教程,因此如果您走這條路,您應該能夠找到相當數量的資源。


查看完整回答
反對 回復 2023-07-14
  • 1 回答
  • 0 關注
  • 229 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號