除了JSON之外,是否有其他序列化句柄的方法?我认为IndexedDB可能会自动完成,但似乎也行不通。文件句柄是可序列化的,这意味着您可以将文件句柄保存到IndexedDB中,或调用postMessage()将它们发送到同一顶层来源。
除了JSON之外,是否有其他序列化句柄的方法?我认为IndexedDB可能会自动完成,但似乎也行不通。文件句柄是可序列化的,这意味着您可以将文件句柄保存到IndexedDB中,或调用postMessage()将它们发送到同一顶层来源。
这里是一个最简示例,演示了如何在IndexedDB中存储和检索文件句柄(确切地说是FileSystemHandle
),代码使用idb-keyval库为了简洁起见:
import { get, set } from 'https://unpkg.com/idb-keyval@5.0.2/dist/esm/index.js';
const pre = document.querySelector('pre');
const button = document.querySelector('button');
button.addEventListener('click', async () => {
try {
const fileHandleOrUndefined = await get('file');
if (fileHandleOrUndefined) {
pre.textContent =
`Retrieved file handle "${fileHandleOrUndefined.name}" from IndexedDB.`;
return;
}
// This always returns an array, but we just need the first entry.
const [fileHandle] = await window.showOpenFilePicker();
await set('file', fileHandle);
pre.textContent =
`Stored file handle for "${fileHandle.name}" in IndexedDB.`;
} catch (error) {
alert(error.name, error.message);
}
});
我已经创建了一个演示,展示了上述代码的实际效果。
当一个平台接口被 [Serializable]
标记时,它意味着它具有相关的内部序列化和反序列化规则,这些规则将被执行“结构化克隆”算法的API使用来创建JS值的“副本”。正如提到的那样,结构化克隆被消息API所使用。在理论上,历史API也使用了它,因此你可以将FileHandle对象与历史记录条目相关联以进行持久化。
在撰写本文时,在Chromium中,FileHandle
对象似乎与 history.state
一起使用时有成功的序列化和反序列化,例如在重新加载和后退导航时。奇怪的是,当返回到前进的条目时,反序列化可能会默默失败:当遍历到与一个或多个FileHandles相关联的状态时,popStateEvent.state 和 history.state总是返回 null。这似乎是一个错误。
历史记录条目是“会话”存储“架子”的一部分。这里的会话指的是(大致)“选项卡/窗口的生命周期”。对于FileHandle来说,这有时可能正好是你想要的(例如,在向后遍历时,重新打开在早期状态下打开的文件)。但它并不能帮助处理跨多个会话粘滞的“源架子”生命周期存储。就我所知,唯一能够将FileHandle序列化和反序列化以进行源级别存储的API是IndexedDB。
对于那些使用Dexie与IndexedDB进行接口交互的人,除非您将主键未命名(“不是入站”),否则您将得到一个空对象:
db.version(1).stores({
test: '++id'
});
const [fileHandle] = await window.showOpenFilePicker();
db.test.add({ fileHandle })
这将导致一个带有{ fileHandle: {} }
(空对象)的记录
然而,如果您不命名主键,则会正确地序列化该对象:
db.version(1).stores({
test: '++'
});
const [fileHandle] = await window.showOpenFilePicker();
db.test.add({ fileHandle })
结果:{ fileHandle: FileSystemFileHandle... }
这可能是Dexie的一个错误,如此报告:https://github.com/dfahlander/Dexie.js/issues/1236