javascript - Chrome 扩展程序消息监听器触发两次

标签 javascript google-chrome-extension

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

基本思想是

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

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

background.jscontentscript.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});

背景.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);
});

ma​​nifest.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"]
        }
    ]
  }

最佳答案

manifest.json中声明的后台脚本已经有自己的页面,一个运行它的隐藏后台页面,所以你不应该在弹出窗口中加载它,因为它没有任何意义,以防有API 事件的监听器,后台页面已经在监听它们。在这种情况下,副本还会在弹出窗口打开时创建第二个监听器。

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

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

关于javascript - Chrome 扩展程序消息监听器触发两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63861313/

相关文章:

JavaScript 对象数组未正确推送

javascript - 如何使 FileReader 与 Angular2 一起工作?

javascript - jQuery.map() 解析 select2 ajax 调用的结果

javascript - 如何在不关闭弹出窗口的情况下创建选项卡

javascript - 无法使用注入(inject)的 jQuery

javascript - 有没有一种方法可以用时刻检索日期格式?

javascript - 如何从 Javascript 访问 Oracle Apex 变量?

javascript - 如何让 Chrome 下载 API 等到下载结束?

javascript - chrome 包应用程序中的 eval

javascript - 从 chrome.history.search() 回调返回一个字符串