Chrome扩展消息侦听器触发两次

时间:2020-09-12 14:24:28

标签: javascript google-chrome-extension

我正在使用Chrome扩展程序。我尝试学习内容和背景之间的消息传递。我为此开发了一个简单的项目。但是我有问题。

基本思想是

  • 扩展名弹出窗口上的用户单击按钮
  • (bot.js)函数从选项卡的内容中查找图像,然后扩展名(background.js)将下载该图像。

问题是 background.js 中的 port.onMessage.addListener()被触发了两次。

background.js将消息发送到contentscript.js 时,控制台中有两条相同的消息,或者当我尝试在background.js中下载(代码行“ Do Something”)时,它会下载文件两次。

我该如何解决这个问题?

popup.html

<!doctype html>
<html>
  <head>
    <title>Test Plugin</title> 
    <script src="background.js"></script>
    <script src="popup.js"></script>
  </head>
  <body>
    <h1>Test Plugin</h1>
    <button id="btnStart">Button</button>
  </body>
</html>

popup.js

document.addEventListener('DOMContentLoaded', function() {
    var checkPageButton = document.getElementById('btnStart');
    checkPageButton.addEventListener('click', function() {  
      GetImages("Some URL");
    }, false);
  }, false);


  var tab_title = '';
  function GetImages(pageURL){
    // Tab match for pageURL and return index
    chrome.tabs.query({}, function(tabs) {
      var tab=null;      
      for(var i=0;i<tabs.length;i++){
        if(tabs[i].url==undefined || tabs[i].url=="" || tabs[i]==null){}
        else{
          if(tabs[i].url.includes(pageURL)){
            tab=tabs[i];
            break;
          }
        } 
      }
      
      if(tab!=null){
          chrome.tabs.executeScript(tab.id, {
            file: "bot.js"
          }, function(results){
            console.log(results);
          });
      }
    });
  }

bot.js

var thumbImagesCount = document.querySelectorAll('.classifiedDetailThumbList .thmbImg').length;
var megaImageURL=document.querySelectorAll('.mega-photo-img img')[0].src;
console.log(megaImageURL + " from bot.js");
port.postMessage({key:"download", text: megaImageURL});

background.js

chrome.runtime.onConnect.addListener(function (port) {
    console.assert(port.name == "content-script");
    port.onMessage.addListener(function(message) {
        
        console.log(message);
        if(message.key=="download"){
            // Do Something
            // Event fires twice
            port.postMessage({key:"download", text: "OK"});
        }
    })
});

contentscript.js

console.log("content script loaded!");
var port = chrome.runtime.connect({name: "content-script"});
port.onMessage.addListener(function(message){
    console.log(message);
});

manifest.json

{
    "manifest_version": 2,
  
    "name": "Test Extension",
    "description": "This extension will download images from gallery",
    "version": "1.0",
    "icons": { 
        "16": "bot16.png",
        "48": "bot48.png",
       "128": "bot128.png" },
    "browser_action": {
        "default_icon": "bot48.png",
        "default_popup": "popup.html"
    },
    "permissions": [
        "activeTab",
        "downloads",
        "http://*/",
        "https://*/"
    ],
    "background": {
        "persistent": false,
        "scripts": ["background.js"]
    },
    "content_scripts": [
        {
            "matches": ["http://*/*", "https://*/*"],
            "js": ["contentscript.js"]
        }
    ]
  }

1 个答案:

答案 0 :(得分:1)

manifest.json中声明的后台脚本已经有自己的页面,运行时处于隐藏的后台页面,因此您不应在弹出窗口中加载它,因为如果有API事件的侦听器,则它是没有意义的,后台页面已经在监听他们。在这种情况下,副本还会在打开弹出窗口时创建第二个侦听器。

解决方案:不要在弹出窗口中加载background.js。

另请参阅Accessing console and devtools of extension's background.js