对不起,我会努力的。
我需要创建一个扩展,其中弹出窗口包含一个字段和一个按钮。
目标是单击该按钮后,将打开一个新窗口(另一个网站),您必须在此新窗口中发送弹出字段信息。
有我的manifest.json
{
"name": "Webrelief extension",
"version": "1",
"browser_action":
{
"default_icon": "webrelief.ico",
"default_popup": "popup.html",
"default_title": "Webrelief extension - Iello"
},
"background":
{
"scripts": ["background.js"],
"persistent": true
},
"content_scripts": [
{
"run_at": "document_end",
"matches": [
"https://www.iello.pro/iello-c102x3259540",
"https://www.google.com/"
],
"js": ["jquery.min.js","content.js"]
}
],
"permissions": ["tabs","activeTab","<all_urls>"],
"manifest_version": 2,
"content_security_policy": "script-src 'self' https://www.iello.pro/iello-c102x3259540; object-src 'self'"
}
我的background.js
$('#validate').on('click',function(activeTab){
var newURL = "https://www.iello.pro/iello-c102x3259540";
chrome.tabs.create(
{
url: newURL
}, function() {
chrome.tabs.query({active: false, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[tabs.length - 1].id, {greeting: "hello"}, function(response) { // tabs[tabs.length - 1] to get the new windows ? I'm not sure
console.log(response);
});
});
}
);
});
我的content.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ?
"from a content script:" + sender.tab.url :
"from the extension");
if (request.greeting == "hello")
sendResponse({farewell: "goodbye"});
});
还有我的popup.html
<!doctype html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Webrelief Extension</title>
<link href="css/main.css" rel="stylesheet">
</head>
<body>
<img width="400px" src="webrelief_logo.svg" alt="Bannière webrelief">
<hr>
<div>
<textarea placeholder="Veuillez saisir le json ici ..." name="json" id="json_iello" cols="30" rows="10"></textarea>
</div>
<button id="validate">Go !</button>
<script src="background.js"></script>
</body>
</html>
当前,如果我按下按钮,则会打开新窗口,但是在新窗口中没有收到消息。
你能告诉我我的错误
谢谢!
答案 0 :(得分:1)
这里有三个主要问题。
这个问题实际上并没有很好的重复(this是最接近的候选人),但是您遇到的主要问题是时间安排。
打开选项卡后,将在页面被充分加载之前调用create
的回调。您的内容脚本可能根本还没有收听该消息。有了document_end
的时间,几乎可以肯定不是这种情况。
唯一安全的方法是逆向通信:让内容脚本请求数据,这样您就知道数据准备好了。
这导致下一个问题。
当您创建一个焦点的选项卡时,会导致弹出窗口失去焦点并关闭。
发生这种情况时,在那里运行的脚本将终止-就像您关闭了页面的标签一样。
因此,您的其余代码甚至都无法运行(无论之前的问题如何)。您在这里有两个选择:
您可以create a tab设置active: false
。这不会失去焦点,因此弹出窗口保持活动状态,但是对用户而言不太方便,尽管此后您仍然可以使它处于活动状态。
作为无关的说明,当query
之类的函数在其回调中显式返回tabs.create
对象时,您不应该tab
。
更好的选项:您应该将“先打开后再通信”委派给您的背景页面。它不受弹出窗口关闭的影响,通常更适合用作“通信路由器”。
这把我们带到了最后一个问题。
您在清单中将background.js
脚本声明为背景脚本。是什么意思?
这意味着将创建一个单独的,不可见的空白页面,并在运行该脚本的情况下加载该页面。
如果在扩展名的其他位置包含background.js
脚本,则该脚本将不是该脚本的“那个”实例。这将是一个独立的副本,并受其新上下文的所有限制。
非常有力的建议:请勿尝试在代码中重用整个脚本。可以使用一些共享代码(例如,utils.js
拥有一些通用功能,并且包含在各个脚本之前),但是请小心地以描述性方式调用脚本并使用单独的代码。
要与“真实的”背景页面进行交互,您需要send messages(使用chrome.runtime.sendMessage
)。
将所有内容放在一起,您的逻辑应该是:
popup.js
脚本),监听您的UI事件。chrome.storage
中)。chrome.storage
获取用户数据,也可以从后台页面请求(通过runtime.sendMessage
)。担心的是,即使您不想使用用户数据,每次打开目标页面时也会启动内容脚本。您可以实施某种机制以仅使用一次数据(例如,在使用后清除/标记数据),也可以仅使用inject the content script programmatically(尽管在tabs.create
之后您将再次遇到计时问题)