chrome.runtime.sendMessage未捕获错误:要连接的参数无效
chrome.runtime.sendMessage Uncaught Error: Invalid arguments to connect
我在创建Chrome扩展时遇到了一个问题。
我创建了一个<iframe>
,当用户单击我的扩展按钮时,它将被内容脚本嵌入到任何网页中。
在这个<iframe>
中,有一个选择框,当它被更改时,应该向扩展发送回一条消息。
然后,扩展应该从Google电子表格中获取数据,然后将信息发送回<iframe>
。
Mymanifest.json如下(编者注:过滤到相关字段):
{
// manifest.json
"background" : {
"scripts" : ["background.js"]
},
"browser_action": {
"default_icon": "icon-small.png"
},
"content_scripts": [ {
"js": ["jquery-1.11.1.min.js","selectionjfm.js","jquery-ui.min.js","nlp_compromise.js"],
"css":["jquery-ui.css"],
"matches": [ "http://*/*", "https://*/*"],
"all_frames":true,
"run_at": "document_end",
"info.status":"complete", "status": "complete"
}],
// ...
"permissions": [
"identity", "https://accounts.google.com/*", "https://www.googleapis.com/*","https://spreadsheets.google.com/*","tabs","storage","<all_urls>"
],
"web_accessible_resources": [
"jquery-ui.min.js","popup.html","popup.js","inject.js","jquery-1.11.1.min.js","loader.gif"
],
"oauth2": {
"client_id": "xxxxxxxxx.apps.googleusercontent.com",
"scopes": ["https://www.googleapis.com/auth/plus.login","https://spreadsheets.google.com/feeds"]
}
}
这个扩展包括一个选择jfm.js作为内容脚本,它以这种方式插入一个<iframe>
:
// selectionjfm.js - content script as included in manifest.json
var iframe = document.createElement('iframe');
iframe.setAttribute("id", "my_id");
iframe.src = chrome.runtime.getURL('popup.html');
document.body.appendChild(iframe);
但是也注入一个JavaScript文件inject.js这样:
// selectionjfm.js - content script as included in manifest.json
var s = document.createElement('script');
s.src = chrome.runtime.getURL('inject.js');
(document.head || document.documentElement).appendChild(s);
console.log("[Content script 1] added inject.js to the content page");
var s = document.createElement('script');
s.src = chrome.runtime.getURL('jquery-1.11.1.min.js');
(document.head || document.documentElement).appendChild(s);
包含一个选择框。当用户在此框中选择另一个值时,我需要使用Google电子表格API对Google电子表格运行请求。这就是为什么我想向扩展发送一条消息,因为我知道只有从那里我才能使用那些API。
inject.js在触发<iframe>
的选择框上的onchange
事件时等待<iframe>
发送的消息。
// inject.js waitning for message from the iframe
window.addEventListener("message",
function (e) {...
<iframe>
:发送的消息
//poupup.js (iframe source)
var sel = document.getElementById("databaseselect");
sel.addEventListener("change", function (e) {
sendMessTobg("changedatabase",sel.selectedOptions[0].text);
});
然后它尝试向background.js:发送消息
// inject.js
if (e.data.message == "changedatabase") { // recieving message from the iframe : this works fine
if (e.data.data != null) {
console.log("[Content script] trying to send databasechange to extension");
chrome.runtime.sendMessage({
databasechange:true,
content:e.data.data
}, function (reply) {
if (chrome.runtime.lastError) {
console.log("[Content script] failure to send databasechange to extension");
} else {
console.log("[Content script] databasechange with backgroud is a success!");
}
});
}
}
则是chrome.runtime.sendMessage
给出错误:
未捕获错误:要连接的参数无效。
我在另一篇帖子中看到了关于发送扩展ID的内容,但文档中说这不是强制性的,因为如果不提供,ID将是我自己的扩展ID。
这里的问题是inject.js
不再是一个内容脚本。您将它添加到DOM中,它与页面自己的代码变得无法区分。Chrome甚至不再知道它是扩展的一部分(以及哪个扩展)。
因此,它不能以通常的方式调用chrome.runtime.sendMessage
——这就是这个错误的原因。你需要以不同的方式进行沟通。
externally_connectable
不适用于您的案例,因为您希望它在任何网站上运行,并且该方法需要将特定域列入白名单。
因此,逻辑追索权是使用DOM事件与将传递消息的内容脚本进行通信。
但是等一下,您已经在使用DOM事件了。你只是在错误的上下文中发现了它!您的"message"
侦听器必须是一个内容脚本,而不是页面级别的脚本。要么将其添加到selectionjfm.js
中,要么考虑是否真的需要将inject.js
注入到页面中。
- 如何使用 href 连接两个参数
- Stripe Connect Charge-必须作为连接帐户进行身份验证才能使用客户参数
- 如何在 redis 中将 JS 对象传递给它自己的事件参数 - 连接事件上的哨兵
- JavaScript - 在函数内连接 2 个参数不起作用
- 如何在附加的 html 中的字符串上连接 javascript 函数中的参数字符串
- 如何将函数参数值连接到对象文字属性名称中
- 参数内部的连接
- 如何连接函数参数和输入 ID
- 如何在 Angular 中的响应 URL 中捕获参数(条带连接)
- 无参数连接是否有效
- 如何连接参数数量未知的数组
- 用查询参数通知持久连接
- Jquery .find()方法——由逗号连接的dom组成的参数
- 我如何连接参数名称的2个字符串
- 车把 - 调用部分时连接字符串参数
- ng的角度传递参数显示连接到不同的json
- 将一个变量连接为jQuery val()参数
- chrome.runtime.sendMessage未捕获错误:要连接的参数无效
- 选择索引已更改,未将参数传递到 Web 部件连接
- 将函数参数中的多个值连接到一个数组中