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

Chrome扩展getAuthToken过期刷新优化:能否仅刷新一次页面?

解决Token过期后仅需一次刷新(或无需刷新)即可生效的问题

我来帮你搞定这个问题——你当前的流程需要两次刷新,核心原因是:页面加载时直接读取了存储中的旧Token,触发401后虽然后台刷新了Token,但当前页面的Content Script没有主动获取新Token,必须等第二次刷新才能读取到更新后的值。我们可以通过以下优化让流程只需要一次刷新,甚至无需刷新页面就能自动恢复:

优化思路

  1. 让Background主动管理Token有效性:不要让Content Script直接读Storage拿Token,而是每次需要Token时向Background请求,Background确保返回的是有效Token(过期自动刷新)。
  2. 401触发刷新后直接复用新Token:遇到401错误时,刷新Token完成后直接用新Token重新发起API请求,无需等待用户刷新页面。

修改后的代码

1. Background.js(核心修改)

我们封装一个获取有效Token的函数,同时完善消息监听逻辑:

// 封装获取有效Auth Token的函数
function getValidAuthToken(callback) {
  chrome.storage.local.get('token', function(data) {
    const currentToken = data.token;
    
    chrome.identity.getAuthToken({interactive: false}, function(token) {
      // 处理可能的错误(比如Token过期导致获取失败)
      if (chrome.runtime.lastError) {
        // 清除旧缓存Token,重新获取
        chrome.identity.removeCachedAuthToken({token: currentToken}, function() {
          chrome.identity.getAuthToken({interactive: false}, function(newToken) {
            chrome.storage.local.set({token: newToken}, function() {
              callback(newToken);
            });
          });
        });
      } else {
        // 如果获取到的Token和当前存储的不一样,更新存储
        if (token !== currentToken) {
          chrome.storage.local.set({token: token}, function() {
            callback(token);
          });
        } else {
          callback(token);
        }
      }
    });
  });
}

// 初始化获取Token(保留原逻辑)
chrome.identity.getAuthToken({interactive: true}, function(token) {
  chrome.storage.local.set({'token': token}, function() {
    console.log('初始Token已保存');
  });
});

// 监听Content Script的消息
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  // 处理获取有效Token的请求
  if (request.greeting === "getToken") {
    getValidAuthToken(function(token) {
      sendResponse({token: token});
    });
    return true; // 异步响应必须返回true,告知Chrome等待响应
  }
  // 处理401触发的强制刷新请求
  else if (request.greeting === "401") {
    chrome.storage.local.get('token', function(data) {
      const oldToken = data.token;
      chrome.identity.removeCachedAuthToken({token: oldToken}, function() {
        chrome.identity.getAuthToken({interactive: false}, function(newToken) {
          chrome.storage.local.set({token: newToken}, function() {
            // 同时返回新Token,方便Content Script直接复用
            sendResponse({farewell: "success", token: newToken});
          });
        });
      });
    });
    return true; // 异步响应标记
  }
});

2. Content Script(google-docs.js)

修改Token获取逻辑,改为向Background请求,同时优化401后的处理:

// 页面加载时,主动向Background请求有效Token并调用API
function initAPICall() {
  chrome.runtime.sendMessage({greeting: "getToken"}, function(response) {
    const token = response.token;
    console.log('获取到有效Token:', token);
    AjaxCall(token);
  });
}

// 初始化调用
initAPICall();

// Ajax错误处理(修正原代码的语法错误)
$.ajax({
  // ... 你的其他Ajax配置
  error: function (jqXHR, textStatus, errorThrown) {
    console.log('Error: ' + errorThrown + ' / ' + textStatus);
    console.log(jqXHR);
    // 捕获401错误,触发Token刷新
    if (jqXHR.responseJSON?.error?.code === 401) {
      refreshAuthTokenCall();
    }
  }
});

function refreshAuthTokenCall(){
  chrome.runtime.sendMessage({greeting: "401"}, function(response) {
    console.log('Token刷新状态:', response.farewell);
    if(response.farewell === "success"){
      // 直接用刷新后的新Token重新调用API,无需刷新页面
      AjaxCall(response.token);
    }
  });
}

为什么这样修改有效?

  • 页面加载阶段:Content Script不再直接读Storage,而是向Background请求有效Token,Background会自动检查并返回未过期的Token,从根源避免拿到旧Token。
  • 401错误触发后:刷新Token完成后,Background会把新Token直接返回给Content Script,Content Script立刻用新Token重新发起API请求,当前页面就能恢复正常,不需要用户手动刷新。

内容的提问来源于stack exchange,提问作者Manu Blackwell

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 13:12:39