Chrome扩展消息传递困惑:跨脚本数据请求响应问题排查
Chrome扩展脚本间消息通信问题修复
核心问题分析
你遇到的TypeError: Cannot read properties of undefined (reading 'data'),本质是消息处理方没有正确调用sendResponse,大概率是异步请求失败后未处理错误分支,导致请求方收到的response为undefined。另外之前的代码还有几个关键错误:
- 初始监听器缺少
sendResponse参数,无法正常返回数据 - 请求脚本错误地在回调函数前加
await,不符合语法规则 - 异步处理时未明确返回
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
相关产品推荐
相关产品推荐

