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

Chrome扩展消息传递困惑:跨脚本数据请求响应问题排查

Chrome扩展脚本间消息通信问题修复

核心问题分析

你遇到的TypeError: Cannot read properties of undefined (reading 'data'),本质是消息处理方没有正确调用sendResponse,大概率是异步请求失败后未处理错误分支,导致请求方收到的response为undefined。另外之前的代码还有几个关键错误:

  1. 初始监听器缺少sendResponse参数,无法正常返回数据
  2. 请求脚本错误地在回调函数前加await,不符合语法规则
  3. 异步处理时未明确返回true告知Chrome保留消息通道

正确实现方案

方案1:回调式写法

处理数据的脚本(如background.js):

chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
  if (message.msg === "start") {
    start();
  } else if (message.msg === "stop") {
    stop();
  } else if (message.msg === "sendData") {
    // 用fetch替代自定义requests(若requests是封装的fetch,需确保返回Promise)
    fetch(base_url + "/projects.json")
      .then(response => {
        // 先校验HTTP响应状态
        if (!response.ok) throw new Error(`请求失败:${response.status}`);
        return response.json();
      })
      .then(result => {
        sendResponse({ data: result });
      })
      .catch(err => {
        // 错误分支必须调用sendResponse,避免请求方收到undefined
        sendResponse({ error: err.message });
      });
    // 必须return true,告诉Chrome等待异步操作完成再关闭消息通道
    return true;
  } else {
    configure();
  }
});

请求数据的脚本:

chrome.runtime.sendMessage({ msg: "sendData" }, function(response) {
  // 先判断是否存在错误
  if (response?.error) {
    console.error("获取数据失败:", response.error);
    return;
  }
  // 正常处理返回数据
  const data = response.data;
  console.log(data);
});

方案2:Promise/await写法(更简洁)

处理数据的脚本:

chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
  if (message.msg === "start") {
    start();
  } else if (message.msg === "stop") {
    stop();
  } else if (message.msg === "sendData") {
    try {
      const response = await fetch(base_url + "/projects.json");
      if (!response.ok) throw new Error(`请求失败:${response.status}`);
      const result = await response.json();
      sendResponse({ data: result });
    } catch (err) {
      sendResponse({ error: err.message });
    }
    // 异步操作必须return true
    return true;
  } else {
    configure();
  }
});

请求数据的脚本:

async function fetchData() {
  try {
    const response = await chrome.runtime.sendMessage({ msg: "sendData" });
    if (response?.error) {
      console.error("获取数据失败:", response.error);
      return;
    }
    const data = response.data;
    console.log(data);
  } catch (err) {
    console.error("消息发送失败:", err);
  }
}

// 调用函数触发数据请求
fetchData();

关键注意事项

  • 当监听器内包含异步操作时,必须return true,否则Chrome会在监听器函数执行完毕后立即关闭消息通道,导致sendResponse失效。
  • 无论异步请求成功还是失败,都要调用sendResponse,避免请求方收到undefined。
  • 如果使用自定义的requests函数,需确保它返回Promise,否则then或await无法正常生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 21:30:59