对于我的扩展程序,我有popup.html
和background.html
。在后台,当互联网连接恢复时,我会收听window.online
事件和chrome.runtime.reload()
。但是,如果互联网脱机并联机,则弹出窗口打开,而弹出窗口保持不变时仅重新加载后台页面。然后,TypeError
从下面的部分
apiFunctions.setHandleRequest('getBackgroundPage', function() {
return GetExtensionViews(-1, 'BACKGROUND')[0] || null;
});
GetExtensionViews(-1,' BACKGROUND')返回undefined
,因此它会尝试访问undefined[0]
。为什么会发生这种情况?我将如何解决这个问题?
答案 0 :(得分:2)
处理您正在做的事情的最佳方法是不在内容脚本中处理在线/离线。在内容脚本中处理此类事件的问题是,在后台脚本中,您正在重新加载。重新加载后,所有内容脚本都无法与后端通信。例如,
如果从内容脚本到后端执行chrome.runtime.sendMessage
重新加载,则会抛出一个无法与后端通信的错误。这将在刷新选项卡之前发生。
因为你似乎经常重新加载,所以
可能更好重新加载后,将内容脚本重新注入所有打开的标签页。例如,后端代码将读取您的清单并重新注入所有内容脚本。这些新的内容脚本可以与您的后端通信。只需确保它们是否插入了删除旧DOM或CSS的任何DOM或CSS,这样您就不会在页面中出现重复元素,这将是一个用户界面错误。
function isSafeToInjectTo(tabs, i) {
if (!tabs[i].url) return false;
var httpOrHttps = tabs[i].url.indexOf('http://') !== -1 || tabs[i].url.indexOf('https://') !== -1;
if (!httpOrHttps) return false;
var googleWebstoreSite = tabs[i].url.indexOf('https://chrome.google.com/webstore') !== -1;
if (googleWebstoreSite) return false;
return true;
}
//THIS CODE SHOULD BE PLACED IN BACKGROUND PAGE AND WILL ONLY RUN ONCE WHEN BACKGROUND SCRIPT STARTS
console.log('injecting ');
var js = [];
var css = [];
chrome.runtime.getManifest().content_scripts.forEach(function (element, index, array) {
$.each(element.js, function (i, el) {
if ($.inArray(el, js) === -1) js.push(el);
});
$.each(element.css, function (i, el) {
if ($.inArray(el, css) === -1) css.push(el);
});
})
chrome.tabs.query({}, function (tabs) {
for (var i in tabs) {
//not able to inject into chrome:// or other non web pages and on google web store - extension has restrictions
if (isSafeToInjectTo(tabs, i)) {
//RE INJECT ALL JS
for (var s in js) {
chrome.tabs.executeScript(tabs[i].id, {file: js[s]});
}
//RE INJECT ALL CSS
for (var c in css) {
chrome.tabs.insertCSS(tabs[i].id, {file: css[c]});
}
}
}
});
不要在线上/线下重新加载,而是在XHR请求中在线/离线处理,只需设置一个短暂的定时器循环setTimeout()
/ setInterval()
来重试或使用框架来处理这个问题对你而言。