tl;dr
Chrome 61 版即將推出更多瀏覽器,現在可透過以下項目顯示網頁應用程式的預估儲存空間用量:
if ('storage' in navigator && 'estimate' in navigator.storage) {
navigator.storage.estimate().then(({usage, quota}) => {
console.log(`Using ${usage} out of ${quota} bytes.`);
});
}
現代化的網頁應用程式和資料儲存空間
當您思考新型網頁應用程式的儲存空間需求時,會將儲存的「內容」分為兩類:載入網頁應用程式所需的核心資料,以及應用程式載入後,進行有意義的使用者互動所需的資料。
第一種資料是載入網頁應用程式所需的資料,由 HTML、JavaScript、CSS 和一些圖片組成。Service Worker 和 Cache Storage API 提供儲存這些核心資源所需的基礎架構,稍後用於快速載入網頁應用程式,理想情況下,應該完全略過網路。(與網頁應用程式建構程序整合的工具 (例如新的 Workbox 程式庫或舊版 sw-precache
),可以完全自動處理儲存、更新及使用這類資料的程序。)
但其他類型的資料呢?這些資源在載入網頁應用程式時並非必要,但對於整體使用者體驗來說至關重要。舉例來說,當您編寫圖片編輯網頁應用程式時,您可能會想儲存一或多個映像檔的本機副本,讓使用者可在修訂版本之間切換並復原工作。如果您正在開發離線媒體播放體驗,將音訊或影片檔案儲存在本機會成為重要功能。凡是可個人化的網頁應用程式,最終都需要儲存某些狀態資訊。如何得知這類執行階段儲存空間還有多少可用空間?儲存空間用盡時會發生什麼情況?
過去時間:window.webkitStorageInfo
和navigator.webkitTemporaryStorage
瀏覽器過去曾透過前置字串等前置字串支援這類自我檢查,例如非常舊 (和已淘汰) 的 window.webkitStorageInfo
,以及不具等效的 navigator.webkitTemporaryStorage
,但仍屬於非標準 navigator.webkitTemporaryStorage
。雖然這些介面提供了實用資訊,但與網路標準無關。
這時 WHATWG Storage Standard 就會在這裡輸入圖片。
未來趨勢:navigator.storage
為持續瞭解儲存空間存取標準,一些實用的 API 已提供了一些實用的 API 供 StorageManager
介面使用,該介面會以 navigator.storage
的形式向瀏覽器顯示。和許多其他較新的網路 API 一樣,navigator.storage
「僅可在安全」(透過 HTTPS 或 localhost 提供) 來源上使用。
我們在去年推出 navigator.storage.persist()
方法,可讓網頁應用程式要求儲存空間不受自動清理功能的影響。
現已透過 navigator.storage.estimate()
方法加入,該方法可做為 navigator.webkitTemporaryStorage.queryUsageAndQuota()
的新型替代項目。estimate()
會傳回類似資訊,但會公開以 promise 為基礎的介面,而此介面與其他新型非同步 API 保持同步。estimate()
傳回的承諾會使用包含兩個屬性的物件解析:usage
(代表目前使用的位元組數量),以及 quota
(代表目前來源可儲存的位元組上限)。(如同其他所有與儲存空間相關的項目,配額適用於整個來源。)
如果網頁應用程式嘗試儲存 (例如使用 IndexedDB 或 Cache Storage API),如果資料夠大,導致特定來源超過可用配額,該要求就會失敗,並出現 QuotaExceededError
例外狀況。
實際儲存空間預估費用
確切使用 estimate()
的方式取決於應用程式需要儲存的資料類型。舉例來說,您可以在介面中更新控制項,讓使用者瞭解每項儲存空間作業完成後的用量。接下來,建議你提供一個介面,讓使用者手動清除不再需要的資料。您可以按照以下程式碼行編寫程式碼:
// For a primer on async/await, see
// https://developers.google.com/web/fundamentals/getting-started/primers/async-functions
async function storeDataAndUpdateUI(dataUrl) {
// Pro-tip: The Cache Storage API is available outside of service workers!
// See https://googlechrome.github.io/samples/service-worker/window-caches/
const cache = await caches.open('data-cache');
await cache.add(dataUrl);
if ('storage' in navigator && 'estimate' in navigator.storage) {
const {usage, quota} = await navigator.storage.estimate();
const percentUsed = Math.round(usage / quota * 100);
const usageInMib = Math.round(usage / (1024 * 1024));
const quotaInMib = Math.round(quota / (1024 * 1024));
const details = `${usageInMib} out of ${quotaInMib} MiB used (${percentUsed}%)`;
// This assumes there's a <span id="storageEstimate"> or similar on the page.
document.querySelector('#storageEstimate').innerText = details;
}
}
預估值的準確度有多高?
您從函式回傳的資料並不容易,因為這只是來源所使用空間的估計值。它就在函式名稱中!usage
和 quota
值都無法保持穩定,因此建議您考量下列事項:
usage
會反映特定來源在使用相同來源資料時能有效使用多少位元組,進而可能受到內部壓縮技術、可能包含未使用空間的固定大小配置區塊,以及刪除後暫時建立的「空值標記」記錄所影響。為避免精確大小資訊外洩,本機儲存的跨來源不透明資源可能會為整體usage
值產生額外的邊框間距位元組。quota
代表目前為來源保留的空間大小。這個值取決於一些常數因素,例如整體儲存空間大小,以及一些潛在的波動因素,包括目前未使用的儲存空間量。因此,就像裝置上的其他應用程式寫入或刪除資料一樣,瀏覽器願意投入網頁應用程式來源的空間量可能會改變。
簡報內容:功能偵測和備用
從 Chrome 61 開始,estimate()
預設為啟用。Firefox 目前正在測試 navigator.storage
,但自 2017 年 8 月起,這項功能預設為停用。您必須啟用 dom.storageManager.enabled
偏好設定才能進行測試。
如要使用部分瀏覽器尚未支援的功能,則必須使用功能偵測。您可以在舊版 navigator.webkitTemporaryStorage
方法之上,結合功能偵測以及承諾型包裝函式,在下列幾行程式碼提供一致的介面:
function storageEstimateWrapper() {
if ('storage' in navigator && 'estimate' in navigator.storage) {
// We've got the real thing! Return its response.
return navigator.storage.estimate();
}
if ('webkitTemporaryStorage' in navigator &&
'queryUsageAndQuota' in navigator.webkitTemporaryStorage) {
// Return a promise-based wrapper that will follow the expected interface.
return new Promise(function(resolve, reject) {
navigator.webkitTemporaryStorage.queryUsageAndQuota(
function(usage, quota) {resolve({usage: usage, quota: quota})},
reject
);
});
}
// If we can't estimate the values, return a Promise that resolves with NaN.
return Promise.resolve({usage: NaN, quota: NaN});
}