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

Chrome扩展OAuth流程:授权后无法关闭弹窗返回原标签页

Chrome扩展OAuth弹窗问题解决方案

问题1:弹窗未显示在浏览器所在屏幕

当前代码以主屏幕为基准计算弹窗位置,但若发起授权的标签页在非主显示器上,弹窗就会错位。应基于当前活动窗口(发起授权的窗口)所在的显示器来定位弹窗:

export const openPopupWindow = async (url: string): Promise<chrome.windows.Window> => {
  const popupWidth = 520;
  const popupHeight = 520;

  // 获取发起授权的当前活动窗口
  const currentWindow = await chrome.windows.getCurrent({ populate: false });
  if (!currentWindow) return;

  // 找到当前窗口所在的显示器
  const displays = await chrome.system.display.getInfo();
  const targetDisplay = displays.find(display => {
    const winLeft = currentWindow.left || 0;
    const winTop = currentWindow.top || 0;
    return winLeft >= display.bounds.left &&
           winLeft < display.bounds.left + display.bounds.width &&
           winTop >= display.bounds.top &&
           winTop < display.bounds.top + display.bounds.height;
  }) || displays[0]; // 找不到则 fallback 到第一个显示器

  // 计算弹窗在目标显示器的居中位置
  const left = Math.round(
    targetDisplay.bounds.left + (targetDisplay.bounds.width - popupWidth) / 2
  );
  const top = Math.round(
    targetDisplay.bounds.top + (targetDisplay.bounds.height - popupHeight) / 2
  );

  return new Promise((resolve) =>
    chrome.windows.create(
      {
        type: "popup",
        focused: true,
        width: popupWidth,
        height: popupHeight,
        left,
        top,
        url: url
      },
      (window) => resolve(window || undefined)
    )
  );
};

问题2:无法获取标签页URL变化

popupWindow.tabs[0]是创建窗口时的静态快照,不会自动更新。改用chrome.tabs.onUpdated事件监听URL变化,比轮询更高效准确:

async function connect(authUrl: string, successCallback?: SuccessCallback): Promise<void> {
  const popupWindow = await openPopupWindow(authUrl);
  if (!popupWindow || !popupWindow.tabs?.[0]) return;

  const popupTabId = popupWindow.tabs[0].id;
  if (!popupTabId) return;

  // 监听标签页URL更新
  const onTabUpdated = async (tabId: number, changeInfo: chrome.tabs.TabChangeInfo) => {
    if (tabId !== popupTabId || !changeInfo.url) return;

    if (changeInfo.url.startsWith("https://localhost")) {
      successCallback?.();
      // 关闭授权弹窗
      await chrome.windows.remove(popupWindow.id!);
      // 移除监听避免内存泄漏
      chrome.tabs.onUpdated.removeListener(onTabUpdated);
    }
  };
  chrome.tabs.onUpdated.addListener(onTabUpdated);

  // 监听弹窗手动关闭事件,清理监听
  const onWindowRemoved = (windowId: number) => {
    if (windowId === popupWindow.id) {
      chrome.tabs.onUpdated.removeListener(onTabUpdated);
      chrome.windows.onRemoved.removeListener(onWindowRemoved);
    }
  };
  chrome.windows.onRemoved.addListener(onWindowRemoved);
}

关键优化点

  • 弹窗定位:从主屏幕改为发起窗口所在显示器,确保弹窗和用户操作的浏览器在同一屏幕。
  • URL监听:用Chrome原生事件替代轮询,实时捕获重定向URL,同时避免无效的重复查询。
  • 资源清理:增加窗口关闭监听,防止用户手动关闭弹窗后残留事件监听导致内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 04:30:29