You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js PWA开发:如何基于Axios实现HTTP请求离线缓存策略?

嘿,这个需求刚好是PWA的核心场景之一,结合Service Worker(SW)和一点Axios的封装就能完美实现,我给你一步步拆解:

核心实现思路

我们需要两种层面的配合:一是利用PWA的Service Worker拦截网络请求,实现「优先网络、失败 fallback 缓存」的全局策略;二是可以在Axios层面做本地缓存的补充,应对更灵活的业务场景。


1. 用Service Worker实现全局请求缓存拦截

Service Worker是PWA实现离线能力的核心,它可以在后台拦截所有网络请求,帮我们处理缓存逻辑。

编写Service Worker代码

创建service-worker.js文件放在项目根目录:

const CACHE_NAME = 'app-api-cache-v1'; // 缓存版本,更新时修改版本号即可清旧缓存

// 安装SW时预缓存必要资源(可选,比如你的接口地址可以提前加入)
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(cache => cache.addAll([
        // '/api/your-target-url' // 可选:预缓存目标接口
      ]))
  );
});

// 拦截所有fetch请求,实现网络优先策略
self.addEventListener('fetch', (event) => {
  // 只处理我们需要的接口请求,避免拦截静态资源
  if (event.request.url.includes('your-api-domain')) {
    event.respondWith(
      // 第一步:尝试网络请求
      fetch(event.request)
        .then(networkRes => {
          // 网络请求成功,更新缓存
          caches.open(CACHE_NAME).then(cache => {
            cache.put(event.request, networkRes.clone());
          });
          return networkRes;
        })
        .catch(() => {
          // 网络失败,从缓存读取数据
          return caches.match(event.request);
        })
    );
  }
});

// 激活SW时清理旧缓存
self.addEventListener('activate', (event) => {
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.filter(name => name !== CACHE_NAME)
          .map(name => caches.delete(name))
      );
    })
  );
});

在Vue项目中注册Service Worker

在main.js中加入注册逻辑:

if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/service-worker.js')
      .then(reg => console.log('Service Worker注册成功:', reg))
      .catch(err => console.error('Service Worker注册失败:', err));
  });
}

2. Axios层面的本地缓存补充(可选)

如果需要更细粒度的控制(比如给缓存加过期时间),可以封装Axios请求,结合localStorage做本地数据缓存:

// 封装带缓存的请求函数
async function fetchWithCache(url, callback) {
  try {
    // 优先发起网络请求
    const res = await axios.get(url);
    // 把数据存入localStorage,带上时间戳
    localStorage.setItem('app_cached_data', JSON.stringify({
      data: res.data,
      timestamp: Date.now()
    }));
    callback(res.data);
  } catch (err) {
    // 网络失败,读取本地缓存
    const cachedStr = localStorage.getItem('app_cached_data');
    if (cachedStr) {
      const cachedObj = JSON.parse(cachedStr);
      // 可选:判断缓存是否过期(比如7天有效期)
      const isExpired = Date.now() - cachedObj.timestamp > 7 * 24 * 60 * 60 * 1000;
      if (!isExpired) {
        callback(cachedObj.data);
        return;
      }
    }
    // 无缓存或缓存过期时的错误处理
    console.error('无网络连接且无有效缓存');
    callback(null);
  }
}

// 使用示例
const targetUrl = '你的接口地址';
fetchWithCache(targetUrl, (data) => {
  if (data) {
    // 处理获取到的数据(不管是网络还是缓存来的)
    console.log('拿到数据:', data);
  }
});

3. Vue CLI项目的简化方案

如果你的项目是用Vue CLI创建的,直接使用@vue/cli-plugin-pwa插件可以省去手动写SW的麻烦,只需要在vue.config.js中配置缓存策略:

module.exports = {
  pwa: {
    workboxOptions: {
      runtimeCaching: [
        {
          // 匹配你的接口地址
          urlPattern: /^https:\/\/your-api-domain\/.*/,
          // 采用「网络优先」策略,符合你的需求
          handler: 'NetworkFirst',
          options: {
            cacheName: 'api-cache',
            // 只缓存200状态的响应
            cacheableResponse: { statuses: [0, 200] }
          }
        }
      ]
    }
  }
};

内容的提问来源于stack exchange,提问作者H. K.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:59:13