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

Chrome扩展反复触发Unchecked runtime.lastError错误,sendResponse提前调用无法等待异步URL分析完成

Chrome扩展反复触发Unchecked runtime.lastError错误,sendResponse提前调用无法等待异步URL分析完成

兄弟,我太懂你这个头疼的问题了!本质上就是异步操作没等完就急着响应导致的——你的analyzePageGuest里用了fetch的链式.then(),这玩意儿是异步的,函数会直接跳过它继续往下走,结果sendResponse先执行了,等后面fetch的回调跑完再想处理就晚了,自然触发runtime.lastError。

给你一步步解决:

第一步:把异步逻辑改成async/await风格,让代码“等一等”

你已经把analyzePageGuest声明成async函数了,完全可以把.then()换成await,这样代码会老老实实等请求完成再继续,不会提前跑路:

async function analyzePageGuest(tabId, changeInfo, tab) {
  const url = tab.url;
  console.log('URL:', url);
  let analysisIdValue;
  try {
    const options = {
      method: 'POST',
      headers: {
        accept: 'application/json',
        'x-apikey': '你的API密钥', // 别硬编码!后面说怎么存
        'content-type': 'application/x-www-form-urlencoded',
      },
      body: new URLSearchParams({ url: url }),
    };

    // 用await等待fetch请求完成,代替.then()
    const response = await fetch(
      'https://www.virustotal.com/api/v3/urls', // 后面说去掉cors-anywhere的方法
      options
    );
    const responseData = await response.json();
    console.log(responseData);
    analysisIdValue = responseData.data.id; // 假设你要拿这个分析ID

    // 如果还要查分析结果,继续用await
    const analysisResponse = await fetch(
      `https://www.virustotal.com/api/v3/analyses/${analysisIdValue}`,
      {
        method: 'GET',
        headers: {
          accept: 'application/json',
          'x-apikey': '你的API密钥',
        },
      }
    );
    const analysisResult = await analysisResponse.json();
    console.log('分析结果:', analysisResult);

    // 把结果返回给调用方
    return analysisResult;
  } catch (error) {
    console.error('分析出错:', error);
    throw error; // 抛出错误让调用者处理
  }
}

第二步:处理消息监听/标签页触发逻辑,确保响应在异步完成后发送

如果是通过chrome.runtime.onMessage接收请求并响应,直接用async回调配合await就行,不用手动返回true(Chrome会自动识别Promise并等待):

chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
  if (request.action === 'analyzePage') {
    try {
      // 等analyzePageGuest跑完再发响应
      const result = await analyzePageGuest(sender.tab.id, {}, sender.tab);
      sendResponse({ success: true, data: result });
    } catch (error) {
      sendResponse({ success: false, error: error.message });
    }
  }
});

如果是在chrome.tabs.onUpdated里触发分析,同样用await等结果出来再给内容脚本发消息:

chrome.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {
  // 只在页面加载完成且是http/https链接时触发
  if (changeInfo.status === 'complete' && tab.url.startsWith('http')) {
    try {
      const analysisResult = await analyzePageGuest(tabId, changeInfo, tab);
      chrome.tabs.sendMessage(tabId, { action: 'analysisResult', data: analysisResult });
    } catch (error) {
      chrome.tabs.sendMessage(tabId, { action: 'analysisError', error: error.message });
    }
  }
});

两个关键优化提醒

  1. 别硬编码API密钥:把密钥存在chrome.storage.local里,用的时候取出来,比如:
    // 存密钥(可以在扩展设置里做个输入框)
    chrome.storage.local.set({ vtApiKey: '你的密钥' });
    // 取密钥
    const { vtApiKey } = await chrome.storage.local.get('vtApiKey');
    
  2. 去掉cors-anywhere:Chrome扩展的背景页本身有跨域权限,只要在manifest.json里加权限就行,不用依赖第三方代理:
    {
      "manifest_version": 3,
      "name": "钓鱼网站检测器",
      "version": "1.0",
      "background": {
        "service_worker": "background.js"
      },
      "host_permissions": ["https://www.virustotal.com/*"],
      "permissions": ["tabs", "storage"]
    }
    

这样改完,你的异步逻辑就会老老实实等分析完成再响应,再也不会触发那个烦人的runtime.lastError了!

备注:内容来源于stack exchange,提问作者Ale26

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 12:53:01