扩展中的错误:获取背景页面

时间:2014-06-14 14:42:03

标签: javascript google-chrome-extension

对于我的扩展程序,我有popup.htmlbackground.html。在后台,当互联网连接恢复时,我会收听window.online事件和chrome.runtime.reload()。但是,如果互联网脱机并联机,则弹出窗口打开,而弹出窗口保持不变时仅重新加载后台页面。然后,TypeError从下面的部分

发生
  apiFunctions.setHandleRequest('getBackgroundPage', function() {
    return GetExtensionViews(-1, 'BACKGROUND')[0] || null;
  });

GetExtensionViews(-1,' BACKGROUND')返回undefined,因此它会尝试访问undefined[0]。为什么会发生这种情况?我将如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

处理您正在做的事情的最佳方法是不在内容脚本中处理在线/离线。在内容脚本中处理此类事件的问题是,在后台脚本中,您正在重新加载。重新加载后,所有内容脚本都无法与后端通信。例如,

如果从内容脚本到后端执行chrome.runtime.sendMessage重新加载,则会抛出一个无法与后端通信的错误。这将在刷新选项卡之前发生。

因为你似乎经常重新加载,所以

可能更好
  1. 重新加载后,将内容脚本重新注入所有打开的标签页。例如,后端代码将读取您的清单并重新注入所有内容脚本。这些新的内容脚本可以与您的后端通信。只需确保它们是否插入了删除旧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]}); 
               }
            }
        }
    });
    
  2. 不要在线上/线下重新加载,而是在XHR请求中在线/离线处理,只需设置一个短暂的定时器循环setTimeout() / setInterval()来重试或使用框架来处理这个问题对你而言。