Chrome扩展chrome.runtime.onMessage异步返回问题求助
问题现象
在Chrome扩展开发中,通过Background脚本检测特定网站Cookie时,调用后立即返回undefined,实际Cookie查询结果几秒后才输出到控制台。尽管在chrome.runtime.onMessage回调中返回了true,仍无法正确等待异步操作完成并返回数据。
原代码
Background.js
chrome.runtime.onMessage.addListener(async function (request, sender, sendResponse) { if (request.contentScriptQuery == 0) { getCookies("https://www.trendyol.com/", "COOKIE_TY.Entrance") .then(m1 =>{console.log('aaa '+m1.status);sendResponse({status:m1.status})}) .catch() return true; } }); function getCookies(domain, name) { return new Promise((resolve, reject) => { try { chrome.cookies.get({ "url": domain, "name": name }, function (cookie) { var r1 = String(String(String(cookie.value).split('&tx=')[1]).split('&')[0]) resolve({ status: true, data: r1 }); }); } catch (err) { resolve({ status: false, data: false }); } }) }
popup.js
class bot { constructor() { this.moderator() } message(status2, data) { return new Promise((resolve, reject) => { chrome.runtime.sendMessage( { contentScriptQuery: status2, data: data }, function (response) { console.log('-----------------------'); console.log('-----------------------'); console.log(response); console.log('---------------'); console.log('---------------'); if (response != undefined && response != "") { resolve(response); } else { reject() } }); }) } async moderator() { var dun = await this.message(0, false) console.log('dun'); console.log(dun); } } window.onload = () => { const user = new bot() }
问题分析
- 错误捕获逻辑失效:
getCookies中的try/catch无法捕获chrome.cookies.get回调内的错误(回调是异步执行的),当Cookie不存在时cookie为undefined,访问cookie.value会直接抛出未捕获的错误,导致Promise无法正确resolve。 - 异常处理缺失:原代码中
getCookies的.catch()分支为空,若发生异常无法调用sendResponse,导致popup端收到undefined响应。 - 字符串拆分逻辑脆弱:多层
String()嵌套和未判断拆分结果是否存在,容易引发数组越界错误。
修复后的代码
Background.js
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { if (request.contentScriptQuery === 0) { getCookies("https://www.trendyol.com/", "COOKIE_TY.Entrance") .then(m1 => { console.log('aaa ' + m1.status); sendResponse({ status: m1.status, data: m1.data }); }) .catch(err => { console.error('获取Cookie失败:', err); sendResponse({ status: false, data: false }); }); return true; // 告知Chrome需等待异步调用sendResponse } }); function getCookies(domain, name) { return new Promise((resolve, reject) => { chrome.cookies.get({ url: domain, name: name }, function (cookie) { try { // 先判断Cookie是否存在 if (!cookie) { resolve({ status: false, data: false }); return; } // 使用可选链简化拆分逻辑,避免数组越界 const r1 = cookie.value.split('&tx=')[1]?.split('&')[0] || ''; resolve({ status: true, data: r1 }); } catch (err) { // 捕获回调内的错误并reject reject(err); } }); }); }
popup.js
class Bot { constructor() { this.moderator(); } message(status2, data) { return new Promise((resolve, reject) => { chrome.runtime.sendMessage( { contentScriptQuery: status2, data: data }, (response) => { console.log('-----------------------'); console.log(response); console.log('-----------------------'); // 捕获消息发送过程中的错误 if (chrome.runtime.lastError) { reject(chrome.runtime.lastError); return; } // 严格判断有效响应 if (response && response.status !== undefined) { resolve(response); } else { reject(new Error('无效的响应数据')); } } ); }); } async moderator() { try { const dun = await this.message(0, false); console.log('dun:', dun); // 根据Cookie检测结果执行对应操作 if (dun.status) { console.log('Cookie存在,提取数据:', dun.data); } else { console.log('Cookie不存在或获取失败'); } } catch (err) { console.error('操作出错:', err); } } } window.onload = () => { new Bot(); };
关键修复点说明
- 将错误捕获逻辑移到
chrome.cookies.get的回调内部,确保能捕获异步操作中的错误。 - 增加Cookie存在性判断,避免访问
undefined的属性。 - 使用可选链
?.简化字符串拆分,防止数组越界报错。 - 完善Promise的异常处理,确保任何情况下都能调用
sendResponse返回结果。 - 在popup端添加
chrome.runtime.lastError检测,捕获消息通信中的错误。
内容的提问来源于stack exchange,提问作者Derviş Aygan
相关产品推荐
相关产品推荐

