导读:本期聚焦于小伙伴创作的《如何实现Service Worker架构中的高效令牌处理与网络请求同步》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何实现Service Worker架构中的高效令牌处理与网络请求同步》有用,将其分享出去将是对创作者最好的鼓励。

Service Worker作为浏览器背后的独立线程,能够拦截页面发出的fetch请求。在需要登录态的系统中,令牌往往有时效限制,如果直接在页面里处理刷新,多标签页并发会导致重复刷新和请求失败。把令牌处理和请求同步放到Service Worker中统一调度,是更稳妥的做法。

如何实现Service Worker架构中的高效令牌处理与网络请求同步

为什么在Service Worker中处理令牌

将令牌逻辑放在Service Worker有以下好处:

  • 所有页面的请求都经过同一处拦截,避免各页面各自刷新令牌。
  • 可以利用worker作用域内的变量缓存令牌,减少反复读取存储的开销。
  • 在离线或弱网时,可先返回缓存响应,待网络恢复后再同步数据。

令牌存储与刷新设计

在worker中使用变量保存access_token和refresh_token,并维护一个刷新中的标记。当发现请求返回401时,进入刷新流程。

// Service Worker内部令牌管理
let tokenData = {
  access_token: null,
  refresh_token: null,
  refreshing: false,
  waiters: []
};

function setTokens(access, refresh) {
  tokenData.access_token = access;
  tokenData.refresh_token = refresh;
}

// 统一刷新令牌,多个请求复用同一次刷新
async function refreshToken() {
  if (tokenData.refreshing) {
    return new Promise(resolve => tokenData.waiters.push(resolve));
  }
  tokenData.refreshing = true;
  try {
    const res = await fetch('/api/refresh', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ refresh_token: tokenData.refresh_token })
    });
    const json = await res.json();
    setTokens(json.access_token, json.refresh_token);
    tokenData.waiters.forEach(fn => fn(json.access_token));
    tokenData.waiters = [];
    return json.access_token;
  } finally {
    tokenData.refreshing = false;
  }
}

网络请求同步实现

在fetch事件中,先给请求附加令牌。若收到401,则刷新令牌后重发原请求,从而保证并发请求不会各自触发刷新。

self.addEventListener('fetch', event => {
  const url = new URL(event.request.url);
  if (url.pathname.startsWith('/api/')) {
    event.respondWith(handleAuthRequest(event.request));
  }
});

async function handleAuthRequest(request) {
  const req1 = addToken(request, tokenData.access_token);
  let response = await fetch(req1);
  if (response.status === 401) {
    const newToken = await refreshToken();
    const req2 = addToken(request, newToken);
    response = await fetch(req2);
  }
  return response;
}

function addToken(request, token) {
  const headers = new Headers(request.headers);
  if (token) {
    headers.set('Authorization', 'Bearer ' + token);
  }
  return new Request(request, { headers: headers });
}

缓存与同步策略

对于非敏感数据,可使用cache-first策略;对于写请求,先发往网络,失败则进入后台同步队列。

请求类型策略说明
GET静态资源cache-first优先读缓存,提升加载速度
GET接口数据network-first保证数据新鲜,失败回退缓存
POST写操作network-only加同步失败存入SyncManager待重发

后台同步示例

self.addEventListener('sync', event => {
  if (event.tag === 'sync-post') {
    event.waitUntil(replayPostQueue());
  }
});

async function replayPostQueue() {
  const cache = await caches.open('post-queue');
  const requests = await cache.keys();
  for (const req of requests) {
    const body = await cache.match(req);
    await fetch(req, { body: await body.blob() });
    await cache.delete(req);
  }
}

小结

通过把令牌刷新收敛到Service Worker、用等待队列消除并发冲突,再配合合理的缓存与后台同步,就能在架构层面实现高效的令牌处理与网络请求同步。这种方案对多标签页应用尤其友好,也更容易扩展到离线优先场景。

Service_Worker令牌处理网络请求同步前端缓存离线优先修改时间:2026-07-24 21:36:29

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。