【发布时间】:2020-09-12 14:24:28
【问题描述】:
我正在开发 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"]
}
]
}
【问题讨论】:
-
manifest.json 中声明的后台脚本已经有自己的页面,一个隐藏的后台页面运行,所以你不应该在弹出窗口中加载它,因为它没有任何意义。在这种情况下,它还会创建第二个侦听器。另见Accessing console and devtools of extension's background.js
-
感谢您的回答。它解决了我的问题。
-
@wOxxOm 看起来我们有一个经典示例,说明为什么不在 cmets 中发布答案或部分答案 - OP 的问题已解决,但问题仍显示为未回答,没有人可以投票,改进,或接受您的解决方案。 :(
-
@IMSoP,问题是,扩展程序有很多活动部件,有时在没有确认猜测正确的情况下发布答案是浪费。
-
@wOxxOm 是的,该平台不适合那种事情,但理想的做法是让 cmets 保留澄清的问题,并将猜测作为答案发布,如果澄清使它们过时,可以随时删除.
标签: javascript google-chrome-extension