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

Chrome扩展消息API实现报错及修正后新问题排查

问题分析与修复方案

我来帮你一步步排查并修复这两个Chrome扩展消息API的问题:

第一个错误:Uncaught TypeError: chrome.runtime.onMessage is not a function

错误原因

在你的popup.js中,你直接调用了chrome.runtime.onMessage(...),但**chrome.runtime.onMessage是一个事件对象,不是可直接执行的函数**。要注册消息监听器,必须使用它的.addListener()方法。

修复代码(popup.js)

把原来的消息监听代码:

chrome.runtime.onMessage(function(message, sender, response){
  console.log(sender);
  if( message.type == 'feed_data' ){
    console.log(message.data);
  }
});

改成:

chrome.runtime.onMessage.addListener(function(message, sender, response){
  console.log(sender);
  if( message.type == 'feed_data' ){
    console.log(message.data);
  }
});

第二个错误:TypeError: Error in invocation of tabs.sendMessage(...):No matching signature

这个错误是由多个小问题叠加导致的,逐一拆解:

错误原因1:标签页ID(tabId)未正确获取

你修改后的background.js里监听了extension_started消息来获取id,但你的代码里没有任何地方发送这个消息,导致id始终是undefined。调用chrome.tabs.sendMessage时,第一个参数必须是有效的标签页ID,传入undefined就会触发签名不匹配的错误。

错误原因2:消息类型不匹配

background.js里发送的消息类型是grab_stories,但你的内容脚本main.js里监听的是grab_feed,两者不一致,导致内容脚本无法响应消息。

错误原因3:内容脚本响应方式错误

你在内容脚本里用了sendResponse({...}),但Chrome消息API的监听器中,第三个参数的名字是response(你自己定义的参数名),正确的响应方式是调用这个response()函数,而不是sendResponse。

修复代码(background.js)

我们直接在收到init_popup_feed消息时,获取当前活跃的标签页ID(假设内容脚本注入到当前活跃页),然后发送正确的消息类型:

chrome.runtime.onMessage.addListener(function(message, sender, response){
  console.log(message.type);
  if( message.type == 'init_popup_feed' ){
    // 获取当前活跃的标签页
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
      const activeTabId = tabs[0].id;
      // 发送与内容脚本匹配的消息类型grab_feed
      chrome.tabs.sendMessage(activeTabId, {type:'grab_feed'}, function(response){
        console.log(response);
        // 把数据转发给popup
        chrome.runtime.sendMessage({type:'feed_data', data:response.data});
      });
    });
  } else if( message.type == 's_feed'){
    chrome.runtime.sendMessage({type:'feed_data', data:message.data});
  }
});

修复代码(main.js - 内容脚本)

修正响应函数的调用方式:

(function($){
  $(document).ready(function(){
    console.log('Extension Started!');
    const l = [];
    var d;
    chrome.runtime.onMessage.addListener(function(message, sender, response){
      console.log(message.type);
      if( message.type == 'grab_feed' ){
        // ... 你的数据抓取代码 ...
        // 用response()发送响应,而不是sendResponse
        response({type:'s_feed', data:l});
        console.log(l);
        // 如果你的数据抓取是异步操作(比如AJAX),需要返回true来保持消息通道开放
        // return true;
      }
    });
  });
}(jQuery));

完整修正后的代码汇总

(function($){
  $(document).ready(function(){
    console.log('Extension Started!');
    chrome.runtime.sendMessage({type:'init_popup_feed'});
    // 正确注册消息监听器
    chrome.runtime.onMessage.addListener(function(message, sender, response){
      console.log(sender);
      if( message.type == 'feed_data' ){
        console.log(message.data);
      }
    });
  });
}(jQuery));

background.js

chrome.runtime.onMessage.addListener(function(message, sender, response){
  console.log(message.type);
  if( message.type == 'init_popup_feed' ){
    // 查询当前活跃标签页
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
      const activeTabId = tabs[0].id;
      chrome.tabs.sendMessage(activeTabId, {type:'grab_feed'}, function(response){
        console.log(response);
        // 转发数据到popup
        chrome.runtime.sendMessage({type:'feed_data', data:response.data});
      });
    });
  } else if( message.type == 's_feed'){
    chrome.runtime.sendMessage({type:'feed_data', data:message.data});
  }
});

main.js(内容脚本)

(function($){
  $(document).ready(function(){
    console.log('Extension Started!');
    const l = [];
    var d;
    chrome.runtime.onMessage.addListener(function(message, sender, response){
      console.log(message.type);
      if( message.type == 'grab_feed' ){
        // ... 你的数据抓取逻辑 ...
        // 正确发送响应
        response({type:'s_feed', data:l});
        console.log(l);
        // 异步操作时取消注释下面一行
        // return true;
      }
    });
  });
}(jQuery));

测试验证

  1. 确保内容脚本已正确注入到目标页面(可以在页面控制台查看Extension Started!日志)
  2. 打开popup,查看popup控制台是否收到数据
  3. 查看background控制台的日志,确认消息传递流程正常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:24:43