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

初级开发者咨询Chrome密码管理器扩展API调用优化方案

优化密码管理器Chrome扩展的Token同步与GraphQL调用方案

当前实现通过每秒轮询获取网站localStorage中的JWT令牌并调用GraphQL接口,存在性能冗余问题。以下是针对性的优化方案,兼顾性能与用户体验:

核心优化思路

  1. 监听Token变化而非定时轮询:仅在网站的id_token发生变更时同步到扩展存储,避免每秒重复执行脚本
  2. 按需触发GraphQL请求:仅当令牌更新时才调用接口,减少不必要的网络请求
  3. 避免重复注入脚本:确保每个目标页面只注册一次监听逻辑,防止内存泄漏

优化后代码实现

1. 改造Token同步逻辑(替换原getBearerKey)

export const initTokenSync = async () => {
  const deployedSite = await chrome.tabs.query({ url: 'https://passwordmanager-zep7.onrender.com/*' });
  const page = deployedSite[0];
  
  if (page) {
    // 检查是否已注册过监听脚本,避免重复注入
    const registeredScripts = await chrome.scripting.getRegisteredContentScripts({ ids: ['token-sync'] });
    if (registeredScripts.length === 0) {
      await chrome.scripting.registerContentScripts([{
        id: 'token-sync',
        matches: ['https://passwordmanager-zep7.onrender.com/*'],
        js: [{ code: `
          // 初始同步一次Token
          const initialToken = localStorage.getItem('id_token');
          chrome.storage.local.set({ bearerKey: initialToken });

          // 监听跨页面的localStorage变化
          window.addEventListener('storage', (e) => {
            if (e.key === 'id_token') {
              chrome.storage.local.set({ bearerKey: e.newValue });
            }
          });

          // 监听同页面内的Token修改(重写setItem)
          const originalSetItem = localStorage.setItem;
          localStorage.setItem = function(key, value) {
            originalSetItem.apply(this, arguments);
            if (key === 'id_token') {
              chrome.storage.local.set({ bearerKey: value });
            }
          };
        ` }],
        runAt: 'document_start'
      }]);
    }
  }
};

2. 改造扩展启动与事件监听(替换原onInstalled逻辑)

import { checkAccounts } from "./api/checkAccounts.js"

chrome.runtime.onInstalled.addListener(async () => {
  // 初始化Token同步
  await initTokenSync();

  // 监听扩展存储中的Token变化,按需触发接口请求
  chrome.storage.local.onChanged.addListener((changes, areaName) => {
    if (areaName === 'local' && changes.bearerKey) {
      const newBearerKey = changes.bearerKey.newValue;
      checkLoginStatus(newBearerKey);
      checkAccounts();
    }
  });
});

// 保留原checkLoginStatus逻辑,无需修改
export const checkLoginStatus = async (bearerKey) => {
  const graphqlEndpoint = 'https://passwordmanager-zep7.onrender.com/graphql';
  const graphqlQuery = `query Me {
    me {
      _id
      username
      email
      password {
        _id
        text
        length
        uppercase
        lowercase
        number
        specialCharacter
      }
      accounts {
        _id
        username
        email
        websiteUrl
        notes
        created
        updated
      }
    }
  }`;

  try {
    const response = await fetch(graphqlEndpoint, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${bearerKey}`
      },
      body: JSON.stringify({ query: graphqlQuery })
    });

    const { data } = await response.json();
    chrome.storage.local.set({ user: data });
  } catch (error) {
    console.error('GraphQL Error:', error);
  }
};

优化说明

  • Token同步效率提升:通过storage事件+重写localStorage.setItem,覆盖了跨页面和同页面的Token修改场景,仅在Token真正变化时同步,彻底消除每秒轮询的性能消耗
  • 接口请求按需触发:GraphQL请求仅在Token更新时执行,避免了每秒重复请求,减轻服务器压力和扩展资源占用
  • 避免重复脚本注入:通过getRegisteredContentScripts检查已注册脚本,防止同一页面多次注入监听逻辑,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 11:21:07