Pan*_*ora 5 javascript jquery json google-chrome-extension indexeddb
I'm上使用IndexedDB的-包装铬扩展工作Dexie,几个jQuery的库和syncfusions eGrid显示和修改数据库。我知道这个问题以前被问过几次,但现在我发现了一些奇怪的行为。
我的设置:
当我重新加载我的扩展程序时,一切都很好。我正在用我的内容脚本注入一个可滚动的名称列表。当我重新加载选项卡时,这也有效。但是当我之前打开 index.html (官方文档中的 popup.html)时,来自后台脚本的 sendResponse 会在一段时间后停止工作。重新加载选项卡将无济于事。我搜索了几个小时,在 googles bugtracker 上找到了很多类似的案例和一些条目,他们声称这个问题已经解决。我也知道如果我有像 indexedDB 这样的异步函数,我必须使用 return true 。
因此,为了给您更多信息,我将列出我缩短的脚本。
内容脚本
chrome.runtime.sendMessage({greeting: 'getNames'},function(response){
$('.names-container').append(response.farewell);
});
chrome.runtime.sendMessage({greeting: 'getData'+name},function(name){
chrome.runtime.sendMessage({greeting: 'delete'},function(response){
console.log(response.farewell);
});
chrome.runtime.sendMessage({greeting: 'set'}, function(response) {
console.log(response.farewell);
});
});
Run Code Online (Sandbox Code Playgroud)
后台脚本
chrome.runtime.onMessage.addListener(function(message,sender,sendResponse){
if(message.greeting == 'getNames'){
// Get array of names from idb and send it back
idb.opendb().then(function(a){
sendResponse(a);
});
return true;
} else if(message.greeting.indexOf('getData') >= 0){
// get more information for selected name
idb.opendb().then(function(a){
sendResponse(a);
});
return true;
} else if(message.greeting == 'delete'){
// further processing to delete some stuff
idb.opendb().then(function(a){
sendResponse(a);
});
return true;
} else if(message.greeting == 'set'){
// synchronous function
// do something ...
return false;
} else {
// Do something
}
//return true;
});
funtion indexhtml(){
chrome.runtime.sendMessage(
"notifications",
function (response) {
console.log(response);
}
);
}
Run Code Online (Sandbox Code Playgroud)
索引.html
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){
if(request == 'notifications'){
notifications();
}
sendResponse("Message received from background-page for "+request);
});
Run Code Online (Sandbox Code Playgroud)
显现
{
"manifest_version": 2,
"name": "MyExtension",
"description": "Some desc...",
"version": "0.2",
"background": {
"scripts": ["js/jquery-2.1.4.min.js", "js/background.js", "...",
"persistent": true
},
"default_locale": "en",
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["js/jquery-2.1.4.min.js"]
},
{
"matches": ["https://domain.tld/*"],
"js": ["js/jquery-2.1.4.min.js", "js/contentscript.js"],
"css" : ["css/contentscript.css",
"run_at": "document_start"
}
],
"icons": {
"16": "images/icon-16x16.png",
"48": "images/icon-48x48.png",
"128": "images/icon-128x128.png"
},
"browser_action": {
"default_icon": "images/icon-128x128.png"
},
"permissions": [
"cookies", "tabs", "alarms", "webRequest", "webRequestBlocking",
"contextMenus", "<all_urls>", "storage"
],
"content_security_policy": "script-src 'self' 'unsafe-eval';
object-src 'self'"
}
Run Code Online (Sandbox Code Playgroud)
我很难调试这种行为,因为我无法确切知道错误何时Attempting to use a disconnected port object出现。在执行 sendResponse 之后,并且仅在打开 index.html 时,端口似乎没有正确关闭。
最后是缩短的错误消息:
Error: Attempting to use a disconnected port object
at Error (native)
at PortImpl.postMessage (extensions::messaging:65:22)
at Port.publicClass.(anonymous function) [as postMessage] (extensions::utils:94:26)
at responseCallback (extensions::messaging:163:16)
Run Code Online (Sandbox Code Playgroud)
idb-Functions 是定制的,不会像我在这里写的那样工作,但我只想展示我在那里做什么。当结果可用时我正在使用.then(),如果异步则等待结果。我还搜索了每个脚本和。列出的与 onMessage/sendMessage 相关的函数都是我正在使用的,它们没有在其他地方使用。我正在使用一个计时器来保存一个包含指定间隔通知的数组,然后在 index.html 执行一个函数来重新加载通知。sendReponsereturn true;onMessagesendMessageindexhtml()
index.html 标签通过 browserAction 打开:
Error: Attempting to use a disconnected port object
at Error (native)
at PortImpl.postMessage (extensions::messaging:65:22)
at Port.publicClass.(anonymous function) [as postMessage] (extensions::utils:94:26)
at responseCallback (extensions::messaging:163:16)
Run Code Online (Sandbox Code Playgroud)
好吧,我在添加越来越多的调试后自己找到了答案。这里的问题是,我正在使用多个(2)onMessage-Listeners。没有特定的侦听器仅侦听发送到我的内容页面(index.html)的消息。每次我打开 index.html 时,如果在我的内容脚本中使用了 sendMessage,则首先会调用附加的 onMessage-Listener。我\xc2\xb4t 不知道这个嵌入到index.html 中的onMessage-Listener 也每次都会被调用。然后,我在内容脚本中更改了 sendMessage 的目的地 - 得到了相同的结果。谷歌文档上还有关于此主题的注释:
\n\n\n\n\n\n\n注意:如果多个页面正在侦听 onMessage 事件,则只有第一个针对特定事件调用 sendResponse() 的页面才会成功发送响应。对该事件的所有其他响应都将被忽略。
\n
第二个问题是,我在 if 子句之外使用了 sendResponse,这样每次都会调用它。所以最后我只需要把 sendResponse 放在 if 子句中,这样只有当后台页面的指定消息通过 sendMessage 调用时它才会被调用。
\n\n背景脚本
\n\nchrome.windows.getAll({populate:true},function(windows){\n windows.forEach(function(window){\n window.tabs.forEach(function(tab){\n if(tab.url.indexOf(chrome.extension.getURL(\'index.html\')) >= 0){\n chrome.tabs.sendMessage(tab.id,{ greeting: "notifications"}, function(response){\n console.log(response);\n });\n }\n });\n });\n});\nRun Code Online (Sandbox Code Playgroud)\n\n索引.html
\n\nchrome.runtime.onMessage.addListener(function(message, sender, sendResponse){\n if(message.greeting == "notifications-trades"){\n Notifications();\n sendResponse("Message received from bg "+message.greeting);\n //if async add return true;\n } else {\n //Do something\n }\n});\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
2664 次 |
| 最近记录: |