需求
在 background 中,拿到了擴展 icon 的 URL 鏈接,如:chrome://extension-icon/mciiogijehkdemklbdcbfkefimifhecn/128/0,如何獲取其二進制數據。
目的:對於記錄擴展安裝卸載的功能而言,能夠獲取擴展的 icon 數據並保存下來,可以優化用戶界面展示。如果此擴展已經卸載,而沒有提前將其 icon 保存,在查看歷史記錄時,就會無法顯示其 icon。
現狀
先說結論:沒有辦法可以實現。
在 Manifest V3 中,background 使用 service-workers 實現,也就是沒有了 BOM 和 DOM 相關的內容。
1 無法使用 Image 元素,讓其幫忙渲染 Icon 圖片。
2 無法使用 XMLHttpRequest 來下載數據。
3 service-worker 中有 fetch,但是其不支持 chrome:// 協議。
所以,就無法獲取到 icon 的具體數據了。
Chrome 的同學收到了反饋,並記錄了 issue,但並沒有打算處理。
How to get the extension icon data in Manifest V3
1257227 - Cannot retrieve extension icons in JS using the chrome.management API - chromium
曲線救國
在討論中,Simeon Vincent 提到了一個曲線救國的方案,在 background 中監聽到有擴展安裝之後,打開一個新的 HTML 頁面(這個頁面是有完整 BOM 和 DOM 支持的),在這個頁面中完成 icon 數據的獲取。
// background.js
chrome.management.onInstalled.addListener((info) => {
spawnSyncIconsPage();
});
function spawnSyncIconsPage() {
return chrome.windows.create({
url: chrome.runtime.getURL('sync-icons.html'),
state: chrome.windows.WindowState.MINIMIZED,
});
}
可以實現目的,但是會打開一個新的頁面,用戶會覺得很奇怪。雖然這個頁面是最小化的,而且完成工作之後會被自動關閉。
service-worker 的其它影響
沒有了 window 對象,上面的掛載也就沒有了。不過,有些內容是支持的,不必在 window 上面去找。
1 indexedDB
如果習慣於使用 window.indexedDB
,還以爲 indexedDB 在 service-worker 不支持了。可以直接使用 indexedDB
2 canvas
在網頁中,習慣使用 HTMLCanvasElement
或者 document.createElement('canvas')
來創建 canvas。
也可以直接使用 OffscreenCanvas