能力 · API
Storage Buckets API
发布于 更新于
navigator.storageBuckets.open(name, options) 创建或打开一个命名的存储桶:它是源存储空间的一个分区,拥有自己的 indexedDB 工厂、caches、桶级文件系统、持久化模式、配额上限和过期时间,因此浏览器可以在存储紧张时逐出低价值的桶,同时保留已持久化的桶。没有桶时,一个源只有一个默认桶,逐出是全有或全无的。
Chrome 122 与 Edge 122 一并提供了 StorageBucketManager 和 StorageBucket 的全部成员(indexedDB、caches、getDirectory()、persist()、estimate()、setExpires());Android 版 Chrome、Samsung Internet 与 Android WebView 镜像该版本。Firefox 尚未实现(Bugzilla 1594740),Safari 没有实现(BCD api.StorageBucketManager)。把桶当作默认桶之上的增强:在 Chrome 上把数据存进 bucket.indexedDB、在其他浏览器存进 window.indexedDB 的页面,可以共用同一套 schema 代码。
navigator.storageBuckets.open(name)navigator.storageBuckets.open(name, options)navigator.storageBuckets.keys()navigator.storageBuckets.delete(name)
bucket.persist()bucket.persisted()bucket.estimate()bucket.setExpires(timestamp)bucket.expires()bucket.getDirectory()open() 返回 Promise<StorageBucket>,keys() 返回存活桶名的 Promise<sequence<DOMString>>,delete() 返回 Promise<undefined>,即使不存在同名桶也会兑现。navigator.storageBuckets 带 [SecureContext],暴露在 Window 与 worker 上;persist() 仅限 Window,因为它可能要查询 persistent-storage 权限。indexedDB 与 caches 属性是作用域限定在桶内的普通 IDBFactory 与 CacheStorage 对象,getDirectory() 返回桶级源私有文件系统的 FileSystemDirectoryHandle。
open() 接受一个桶名和一个可选的 StorageBucketOptions 字典。桶名必须是 1 到 64 个码点的 ASCII 小写字母、数字、_ 或 -,且不能以 _ 或 - 开头;打开已存在的名称会返回已有的桶并忽略 options。
| 成员 | 类型 | 必填 | 说明 |
|---|---|---|---|
persisted |
boolean |
否,默认 false |
请求 "persistent" 桶模式。只有 persistent-storage 权限为 "granted" 时才会生效;否则桶以尽力而为模式打开,bucket.persisted() 兑现为 false。 |
quota |
unsigned long long(字节) |
否 | 桶用量的上限;浏览器可以施加更低的限制。设置后 bucket.estimate() 把它作为 quota 报告。 |
expires |
DOMHighResTimeStamp(自 Unix 纪元起的毫秒数) |
否 | 桶被视为已消失的时间点。过期的桶在下一次 open()、keys() 或访问时被惰性移除。 |
Chromium 的 IDL 还带有一个 durability 成员("strict" 或 "relaxed"),位于 StorageBucketsDurability 运行时标志之后;WICG explainer 已把它从 API 的第一版中移除,因为 IndexedDB 事务本身就暴露同样的 durability 选项,所以不要依赖它。
open() 返回的 StorageBucket 有以下成员。
| 成员 | 类型 | 说明 |
|---|---|---|
name |
DOMString(只读) |
打开桶时使用的键。 |
persist() |
Promise<boolean> |
persistent-storage 权限已授予时升级为 "persistent" 模式;以结果模式兑现。 |
persisted() |
Promise<boolean> |
桶处于 "persistent" 模式时为 true。 |
estimate() |
Promise<StorageEstimate> |
仅此桶的 usage 与 quota,不同于覆盖整个源的 navigator.storage.estimate()。 |
setExpires(ms) / expires() |
Promise<undefined> / Promise<DOMHighResTimeStamp?> |
设置或读取过期时间;未设置时 expires() 兑现为 null。 |
indexedDB、caches、getDirectory() |
IDBFactory、CacheStorage、Promise<FileSystemDirectoryHandle> |
桶级的存储端点。 |
open()、keys() 与 delete() 以拒绝而非抛出的方式报错,唯一的例外是整个 API 对当前上下文不可用时 Chromium 同步抛出的 SecurityError。
| 异常 | 方法 | 条件 |
|---|---|---|
TypeError |
open()、keys()、delete()、estimate() |
无法获得 storage shelf(opaque origin、存储被禁用);open() 还会因桶名无效、expires 早于当前时间、quota 小于等于零而拒绝。 |
InvalidCharacterError |
delete() |
规范规定的桶名无效情形。Chromium 在这里改以 TypeError 拒绝(见实测)。 |
InvalidStateError |
persist()、persisted()、estimate()、setExpires()、expires() |
桶的 removed 标志已置位:你拿到句柄之后它被删除或已过期。 |
QuotaExceededError |
open() |
Chromium 特有:该源创建的桶数量超过实现允许的上限(Too many buckets created.)。 |
UnknownError |
open()、keys()、delete() |
Chromium 特有:存储后端失败(Unknown error occured while creating a bucket.,拼写错误是 Chromium 原文)。 |
SecurityError |
任一方法(同步抛出) | Chromium 在此上下文中拒绝该 API,例如 opaque origin:Access to Storage Buckets API is denied in this context. |
两个示例都先解析出一个存储端点,再让同一套应用代码在它之上运行,这样 Firefox 与 Safari 的回退就是源的默认存储,而不是第二套代码路径。
把草稿放进持久化桶,缺少支持时回退到默认 IndexedDB
Section titled “把草稿放进持久化桶,缺少支持时回退到默认 IndexedDB”草稿是用户最不愿丢失的数据,所以放进一个申请 persisted: true 的桶。navigator.storageBuckets 缺失时,同一个数据库在 window.indexedDB 上打开;持久化请求被拒时,代码如实告知,而不是假定桶是安全的。
function openDatabase(factory, name, version) { return new Promise((resolve, reject) => { const request = factory.open(name, version); request.onupgradeneeded = () => request.result.createObjectStore('drafts', { keyPath: 'id' }); request.onsuccess = () => resolve(request.result); request.onerror = () => reject(request.error); });}
async function openDraftsDatabase() { if (!('storageBuckets' in navigator)) { return { db: await openDatabase(indexedDB, 'drafts', 1), persisted: false }; } const bucket = await navigator.storageBuckets.open('drafts', { persisted: true }); return { db: await openDatabase(bucket.indexedDB, 'drafts', 1), persisted: await bucket.persisted(), // persistent-storage 授予前为 false };}
const { db, persisted } = await openDraftsDatabase();if (!persisted) { document.querySelector('#storage-note').textContent = '草稿以尽力而为方式保存,存储紧张时可能被清除。';}在全新的 Chrome 配置文件中 persisted 会返回 false,因为 persistent-storage 尚未授予;先在用户手势中调用 navigator.storage.persist() 才会改变这一结果。
自行过期的资讯缓存
Section titled “自行过期的资讯缓存”供离线阅读而缓存的资讯流值得保留一周,之后就没有价值。桶带上 expires 时间戳,浏览器会在没有清理任务的情况下移除它;回退分支把同样的响应存进默认 caches,并按记录的日期手动清理。
const WEEK = 7 * 24 * 60 * 60 * 1000;
async function feedCache() { if ('storageBuckets' in navigator) { const bucket = await navigator.storageBuckets.open('feed', { expires: Date.now() + WEEK }); return bucket.caches.open('articles'); } const cache = await caches.open('articles'); const stamp = await cache.match('/__cached-at'); if (stamp && Date.now() - Number(await stamp.text()) > WEEK) { await caches.delete('articles'); return caches.open('articles'); } if (!stamp) await cache.put('/__cached-at', new Response(String(Date.now()))); return cache;}
const cache = await feedCache();await cache.add('/api/feed?page=1');打开已存在的桶不会刷新它的过期时间,所以长期使用的资讯桶需要在每次成功同步后调用 bucket.setExpires(Date.now() + WEEK) 把期限持续后推。
- IndexedDB:面向 PWA 的结构化客户端存储
- 存储持久化、配额与逐出,桶所细化的源级模型
- 配额与 StorageManager.estimate()
- Cache Storage:离线 PWA 背后的请求/响应存储
- Storage Buckets 支持情况
- Storage Buckets API: open() method(wicg.github.io)
- Storage Buckets API: validate a bucket name(wicg.github.io)
- Storage Buckets explainer(github.com)
- Bugzilla 1594740: Implement support for storage buckets(bugzilla.mozilla.org)
规范
| 规范 | 状态 |
|---|---|
| Storage Buckets(存储分桶) | WICG 草案 |
| Storage Buckets API: open() method | WICG 草案 |
| Storage Buckets API: the StorageBucket interface | WICG 草案 |
- 图例
- 支持
- 部分支持
- 需开启标志
- 不支持
- 未知
| 浏览器 / 平台 | 支持 | 版本 | 置信度 | 来源 | 备注 |
|---|---|---|---|---|---|
| Chrome (Desktop) | 支持 | 122 | 低 | 来源 | 12 |
| Chrome (Android) | 支持 | 122 | 低 | 来源 | 3 |
| Edge (Desktop) | 支持 | 122 | 低 | 来源 | 4 |
| Firefox (Desktop) | 不支持 | — | 低 | 来源 | 5 |
| Safari (macOS) | 不支持 | — | 低 | 来源 | 6 |
- 依据 MDN browser-compat-data,StorageBucketManager(navigator.storageBuckets)在 Chrome 122 中发布。
- 该条目尚无 MDN 说明页;依据 caniuse 上该特性的各浏览器支持表核对。
- 依据 MDN browser-compat-data,镜像桌面版 Chrome 的支持情况。
- 依据 MDN browser-compat-data,镜像 Chromium 的支持情况。
- 未实现;依据 MDN browser-compat-data,作为未关闭的 Firefox bug 跟踪中。
- 依据 MDN browser-compat-data,未实现。