window.requestFileSystem已废弃,求存储Blob文件实现离线播放的替代API
替代window.requestFileSystem的Blob存储方案(离线视频场景)
由于window.requestFileSystem已被废弃,针对离线视频播放的Blob存储需求,以下是三种主流替代方案:
1. File System Access API
这是最贴近原API功能的替代方案,允许网页直接与用户本地文件系统交互,支持持久化存储,适合类似YouTube下载页这种需要让用户管理本地下载文件的场景。
核心操作示例:
- 请求用户选择存储目录:
async function getStorageDirectory() { const dirHandle = await window.showDirectoryPicker(); // 可将目录句柄存入IndexedDB,以便后续会话复用 return dirHandle; }
- 将Blob写入目录中的文件:
async function saveBlobToFile(dirHandle, fileName, blob) { const fileHandle = await dirHandle.getFileHandle(fileName, { create: true }); const writable = await fileHandle.createWritable(); await writable.write(blob); await writable.close(); }
- 读取存储的文件用于播放:
async function readFileFromDir(dirHandle, fileName) { const fileHandle = await dirHandle.getFileHandle(fileName); const file = await fileHandle.getFile(); const blobUrl = URL.createObjectURL(file); // 可将blobUrl赋值给video元素的src属性 return blobUrl; }
2. IndexedDB
适合不需要用户直接访问本地文件、仅在后台持久化存储Blob的场景,存储容量远大于localStorage,支持结构化数据管理。
核心操作示例:
- 初始化数据库:
function initVideoDB() { return new Promise((resolve, reject) => { const request = indexedDB.open('OfflineVideoDB', 1); request.onupgradeneeded = (e) => { const db = e.target.result; // 创建存储对象,以视频ID作为主键 db.createObjectStore('videos', { keyPath: 'videoId' }); }; request.onsuccess = () => resolve(request.result); request.onerror = () => reject(request.error); }); }
- 存储Blob:
async function saveBlobToDB(db, videoId, blob) { const transaction = db.transaction('videos', 'readwrite'); const store = transaction.objectStore('videos'); await store.put({ videoId, blob }); await transaction.complete; }
- 读取Blob用于播放:
async function getBlobFromDB(db, videoId) { const transaction = db.transaction('videos', 'readonly'); const store = transaction.objectStore('videos'); const record = await store.get(videoId); if (record) { return URL.createObjectURL(record.blob); } return null; }
3. Cache API(配合Service Worker)
适合PWA应用的离线资源缓存场景,可直接缓存视频请求的响应(Blob形式),用户访问时自动从缓存读取,实现无缝离线播放。
核心操作示例:
- 在Service Worker中拦截并缓存视频请求:
self.addEventListener('fetch', (event) => { // 匹配视频资源请求 if (event.request.url.match(/\.mp4|\.webm$/)) { event.respondWith( caches.open('video-cache-v1').then((cache) => { return cache.match(event.request).then((cachedResponse) => { // 优先返回缓存,无缓存则请求网络并缓存 return cachedResponse || fetch(event.request).then((networkResponse) => { cache.put(event.request, networkResponse.clone()); return networkResponse; }); }); }) ); } });
- 在主页面主动缓存指定视频:
async function cacheTargetVideo(videoUrl) { const cache = await caches.open('video-cache-v1'); await cache.add(videoUrl); }
方案选择建议
- 若需要用户直接管理本地视频文件(重命名、删除、手动选择存储位置),优先选File System Access API。
- 若仅需后台静默存储,无需用户干预,选IndexedDB。
- 若基于PWA构建,需要整站离线资源适配,选Cache API + Service Worker。
内容的提问来源于stack exchange,提问作者Александр Остапенко
相关产品推荐
相关产品推荐

