PWA离线存储策略:IndexedDB与Cache API

Progressive Web Apps (PWA) 使用离线存储策略来提供离线体验,即使在网络不可用时也能访问部分内容。两种主要的离线存储技术是IndexedDB和Cache API(也称为Service Worker Cache)。它们各有特点,适用于不同的场景。

IndexedDB

IndexedDB 是一种键值对存储,适合存储大量结构化数据,如数据库记录、用户设置或较大的文件。它可以进行复杂的查询,并支持事务操作。以下是一个简单的IndexedDB创建、存储和读取数据的例子:

// 打开或创建数据库
let dbPromise = indexedDB.open("myDatabase", 1);

// 当数据库打开成功时
dbPromise.then(function(db) {
    // 创建一个对象存储
    let objectStore = db.createObjectStore("myStore", { keyPath: "id" });

    // 插入数据
    objectStore.add({ id: 1, name: "Alice" });

    // 查询数据
    let transaction = db.transaction(["myStore"], "readonly");
    let store = transaction.objectStore("myStore");
    let request = store.get(1);

    request.onsuccess = function(event) {
        console.log("Retrieved data:", event.target.result);
    };
});

Cache API

Cache API 是Service Worker的一部分,用于缓存网络请求和响应,通常用于静态资源的离线存储。它提供了一种简单的方式来存储和检索URL对应的资源。以下是如何使用Cache API缓存网页资源的示例:

// 在service worker中安装阶段缓存资源
self.addEventListener("install", async event => {
    event.waitUntil(
        caches.open("myCache").then(cache => {
            return cache.addAll([
                "/index.html",
                "/styles.css",
                "/scripts.js"
            ]);
        })
    );
});

// 在fetch事件中,尝试从缓存中获取资源
self.addEventListener("fetch", event => {
    event.respondWith(
        caches.match(event.request).then(response => {
            // 如果缓存中有资源,返回缓存的响应
            if (response) {
                return response;
            } else {
                // 否则,尝试从网络获取资源,并将新资源添加到缓存
                return fetch(event.request).then(networkResponse => {
                    caches.open("myCache").then(cache => {
                        cache.put(event.request, networkResponse.clone());
                    });
                    return networkResponse;
                }).catch(() => {
                    // 网络失败时返回缓存的默认响应
                    return caches.match("/offline.html");
                });
            }
        })
    );

});

在上面的代码中:

install 事件用于初始化缓存,将指定的URL列表添加到缓存中。
fetch 事件监听网络请求,优先尝试从缓存中获取资源。如果缓存中没有,就从网络请求,成功后将新资源存入缓存。如果网络请求失败,返回一个备用的离线页面。

结合使用IndexedDB和Cache API,PWA可以提供离线存储用户数据和静态资源,确保在离线状态下仍然有良好的用户体验。

在实际的PWA应用中,通常会结合使用IndexedDB和Cache API,以实现最佳的离线体验。例如,IndexedDB用于存储用户数据,而Cache API用于存储静态资源。

self.addEventListener("install", async event => {
    event.waitUntil(
        Promise.all([
            caches.open("staticCache").then(cache => {
                return cache.addAll([
                    "/index.html",
                    "/styles.css",
                    "/scripts.js"
                ]);
            }),
            // 假设有一个API获取用户数据
            fetch("/api/user").then(response => {
                return response.json().then(data => {
                    return indexedDB.open("userData", 1).then(db => {
                        let transaction = db.transaction(["userData"], "readwrite");
                        let store = transaction.objectStore("userData");
                        store.put(data);
                    });
                });
            })
        ])
    );
});

self.addEventListener("fetch", event => {
    event.respondWith(
        caches.match(event.request).then(response => {
            if (response) {
                return response;
            }

            // 尝试从网络获取资源
            return fetch(event.request).then(networkResponse => {
                caches.open("staticCache").then(cache => {
                    cache.put(event.request, networkResponse.clone());
                });

                return networkResponse;
            }).catch(() => {
                // 网络失败时,尝试从IndexedDB获取用户数据
                if (event.request.url.endsWith("/api/user")) {
                    return indexedDB.open("userData", 1).then(db => {
                        let transaction = db.transaction(["userData"], "readonly");
                        let store = transaction.objectStore("userData");
                        let request = store.get(1);
                        return request.onsuccess ? request.onsuccess.event.target.result : null;
                    });
                } else {
                    return caches.match("/offline.html");
                }
            });
        })
    );
});
  1. install事件中,同时缓存静态资源并从API获取用户数据,然后将数据存储在IndexedDB中。

  2. fetch事件中,优先从缓存中获取资源。如果缓存中没有,尝试从网络获取。对于API请求,如果网络请求失败,尝试从IndexedDB中获取用户数据。对于其他资源,返回离线页面。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天涯学馆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值