【问题标题】:Chrome Extension: Message Passing from Content to Background ScriptChrome 扩展:从内容到后台脚本的消息传递
【发布时间】:2021-03-31 09:48:29
【问题描述】:

我已经搜索并尝试了从 SO 到这个问题的不同可接受的答案,但它们都不适用于我的情况。我很确定我不明白一些事情。我在 24 小时前刚刚开始了这个 chrome 扩展之旅,所以我承认我有很多东西要学。

不过,我正在尝试为特定网站创建下载器。我有三个 javascript 文件:

  1. script_injection.js”,添加在content_scripts.中,是一个纯javascript调用“injection_ui.js”据我了解,我不能直接在 content_scripts 上使用 chrome APIS,所以我创建了另一个 JS 文件并调用它。
  2. injection_ui.js”,它是“web_accessible_resources”的一部分,将按钮添加到所有图像,并绑定了点击时消息传递的功能。李>
  3. background.js,在background中,监听按钮发送的消息。

manifest.json


{
    "name": "Dummy Extension",
    "version": "1.0",
    "manifest_version": 2,

    "description": "This is a dummy extension.",
    "browser_action": {
        "default_title": "Download Images from Anywhere",
        "default_popup": "popup.html"
    },

    "content_scripts" : [
        {  
            "matches": ["https://dummywebsite.com/*"],
            "js": ["script_injection.js"],
            "css": ["style.css"]
        }
    ],

    "permissions": [
        "storage",
        "downloads",
        "activeTab",
        "declarativeContent"
    ],

    "web_accessible_resources": ["injection_ui.js"],

    "background" : {
        "scripts" : ["jquery.js", "background.js"],
        "persistent" : true
    }
}

script_injection.js


var s = document.createElement('script');
s.src = chrome.runtime.getURL('background.js');
s.onload = function() {
    this.remove();
};
(document.head || document.documentElement).appendChild(s);

injection_ui.js

$(document).ready(function(){
    
    $(".image-thumbnail").each(function(){
        var src = $(this).attr("src");
        $(this).append("<a class='DummyAddedButton' download='"+ src +"'>Download</button>");
    }); 

    $(".DummyAddedButton").off().on("click", function(){
        var source = $(this).attr("src");
        
        chrome.runtime.sendMessage("mlbcmjpahokfgkghabmfjgmnafffphpd", source, function(){
            console.log("sending success: " + source);
        });
    });
});

background.js


chrome.runtime.onMessage.addListener(
    function(message, callback) {
            chrome.downloads.download({url:message, filename:"image.jpg"});
});    

单击按钮时,它会根据 sendMessage 的指示在控制台日志上显示一条消息。但是,它也显示错误:“Unchecked runtime.lastError: Could not建立连接。接收端不存在。”

免责声明。如果我在 popup.js 上使用相同的按钮,它会下载图像。但我想将功能绑定在网站上注入的按钮上,而不是通过扩展面板。

【问题讨论】:

    标签: google-chrome google-chrome-extension


    【解决方案1】:

    目前,您在page context 中注入代码,这既是不必要的过度复杂化,也是错误的,因为您注入的后台脚本已经在与网页无关的扩展程序的隐藏单独背景页面中运行。见how to open background.js devtools and console

    从 manifest.json 和 jquery.js 中删除 script_injection.js、injection_ui.js 和 web_accessible_resources 部分以及不必要的权限。

    根据documentation正确声明onMessage监听器的参数。

    使用"persistent": falsemore info

    {
      "name": "Dummy Extension",
      "version": "1.0",
      "manifest_version": 2,
      "description": "This is a dummy extension.",
      "browser_action": {
        "default_title": "Download Images from Anywhere",
        "default_popup": "popup.html"
      },
      "content_scripts": [{
        "matches": ["https://dummywebsite.com/*"],
        "js": ["content.js"],
        "css": ["style.css"]
      }],
      "permissions": [
        "storage",
        "downloads"
      ],
      "background": {
        "scripts": ["background.js"],
        "persistent": false
      }
    }
    

    让我们使用一个标准名称 content.js,里面有标准 JS,没有 jquery。如果你还想要jquery,那么在manifest.json中声明为"js": ["jquery.js", "content.js"]

    content.js:

    for (const thumb of document.querySelectorAll('.image-thumbnail')) {
      thumb.appendChild(Object.assign(document.createElement('button'), {
        className: 'DummyAddedButton',
        textContent: 'Download',
      }));
    }
    
    document.addEventListener('click', e => {
      if (e.target.matches('.DummyAddedButton')) {
        chrome.runtime.sendMessage(e.target.closest('.image-thumbnail').src);
      }
    });
    

    background.js:

    chrome.runtime.onMessage.addListener((message, sender, sendMessage) => {
      chrome.downloads.download({url: message, filename: 'image.jpg'});
    });    
    

    编辑 manifest.json 或内容脚本后,不要忘记在 chrome://extensions 页面和网页选项卡上重新加载扩展。

    【讨论】:

    • 很抱歉,injection_ui.js 不完整,因此,您的答案缺少部分,特别是在每张图片顶部添加一个按钮会触发下载.我现在已经更新了代码。在您的回答中,我假设您没有考虑这部分流程。
    • 这是微不足道的 DOM 东西,因此可以在 content.js 中,请参阅更新后的答案。
    • 我将代码转换为 jQuery,它现在可以工作了。虽然我仍然不明白我之前代码的哪个特定部分是错误的(除了不必要的文件),但我很高兴它现在可以正常工作。几乎浪费了16个小时。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    • 1970-01-01
    • 2015-11-09
    • 2011-08-31
    • 1970-01-01
    相关资源
    最近更新 更多