Google chrome extension Chrome扩展:后台js无法偶尔从弹出js接收消息

Google chrome extension Chrome扩展:后台js无法偶尔从弹出js接收消息,google-chrome-extension,Google Chrome Extension,弹出窗口上有一个按钮。单击后,popup.js将向background.js发送一条消息。它几乎一直运行良好。但在长时间不操作chrome之后,当我单击按钮时,消息被发送(警报(“开始发送消息”)已执行),但后台无法接收到。js(警报(“开始渲染”)未执行)。当我再单击一个时,它有时会起作用。如果仍然不起作用,我会再次单击,第三次有更多的成功机会。真奇怪 我在popup.html中使用jquery,但我认为这无关紧要。 popup.js中的Javascript代码 $('#create).htm

弹出窗口上有一个按钮。单击后,popup.js将向background.js发送一条消息。它几乎一直运行良好。但在长时间不操作chrome之后,当我单击按钮时,消息被发送(警报(“开始发送消息”)已执行),但后台无法接收到。js(警报(“开始渲染”)未执行)。当我再单击一个时,它有时会起作用。如果仍然不起作用,我会再次单击,第三次有更多的成功机会。真奇怪

我在popup.html中使用jquery,但我认为这无关紧要。 popup.js中的Javascript代码

$('#create).html(chrome.i18n.getMessage('create'))
.on('click', function(){
    _current = null;
    chrome.runtime.sendMessage({
        cmd: 'SITEMAP_DEFINE'
    });
    alert("Start to send message");
    window.close();
})

background.js中的Javascript代码

var curTabId; //current tab in which scraper is going to scraping
var devtoolPort;
var coord;
var sitemap;
var finish = false;


function sendMessage(msg) {
  chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    chrome.tabs.sendMessage(tabs[0].id, msg);
  });
}

//detective devtools
chrome.runtime.onConnect.addListener(function (port) {
    if (port.name == "devtools-papa") {
        devtoolPort = port;
    }
});

//tab update
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
    if(finish === false && coord && changeInfo.status == 'loading'){
        coord.onUpdate(tab);
    }
})
chrome.tabs.onRemoved.addListener(function(tabId, removeInfo) {
    if(finish === false && coord && removeInfo.isWindowClosing === false){
        coord.onRemove(tabId);
    }
})
chrome.runtime.onMessage.addListener(function(msg, sender, callback){
    var p = msg.params;

    //scrape
    if(msg.cmd == 'START_SCRAPE'){
        sitemap = p.sitemap;
        if(sitemap){
            finish = false;
            coord = new Coordinator(sitemap, 0);
            var page = coord.sitemap.pages[0];
            coord.openTab(page.id, page.link);
        }
    }
    else if(msg.cmd == 'TEST_SCRAPE'){
        sitemap = p.sitemap;
        if(sitemap){
            chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
                var tab = tabs[0];
                sitemap.pages[0].link = tab.url;
                finish = false;
                coord = new Coordinator(sitemap, 20);
                var page = coord.sitemap.pages[0];
                coord.openTab(page.id, page.link);
            })
        }
    }
    else if(msg.cmd == 'SCRAPE_READY'){
        print(sender);
        coord.readyForScrape(sender.tab.id);
    }
    else if(msg.cmd == 'TAB_CLICK'){
        coord.currentPage = sitemap.getPage(p.page);
    }

    //define
    else if(msg.cmd == 'START_SELECT'){
        if(msg.tabId){
            chrome.tabs.sendMessage(msg.tabId, msg);
        }else{
            sendMessage(msg);
        }
    }
    else if(msg.cmd == 'END_SELECT'){
        if(devtoolPort){
            devtoolPort.postMessage(msg);
        }
        sendMessage(msg);
    }
    else if(msg.cmd == 'SITEMAP_DEFINE'){
        alert("Start to render");
        var url = p && p.url;
        sitemap = p && p.sitemap;
        chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
            var tab = tabs[0];
            if(url && url != tab.url){
                chrome.tabs.create({url: url}, function(newTab){
                    doInjectScript(newTab.id);
                })
            }else{
                injectScript(tab.id);
            }
        });
    }
    else if(msg.cmd == 'SITEMAP_DEFINE_END'){
        var _sm = p.sitemap;
        chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
            var tab = tabs[0];
            _sm.pages[0].link = tab.url;
            saveSitemap(_sm);
        })
    }
    else if(msg.cmd == 'SITEMAP_DELETE'){
        deleteSitemap(p.sitemap);
    }
    else if(msg.cmd == 'DEFINE_PAGE_LOADED'){
        callback(sitemap);
    }
    else{
        sendMessage(msg);
    }
});

var print = function(msg){
    if(curTabId){
        chrome.tabs.sendMessage(curTabId, {
            cmd: 'LOG',
            params: msg
        });
    }else{
        sendMessage(msg)
    }
}

function saveSitemap(_sm){
    var id = _sm.id;
    chrome.storage.local.get("sitemaps", function(db){
        var _sitemaps = db["sitemaps"];
        if(!_sitemaps || !_sitemaps.length){
            _sitemaps = [_sm];
        }else{
            var _idx = _sitemaps.findIndex(function(s){return s.id == id});
            if(_idx == -1){
                _sitemaps.push(_sm);
            }else{
                _sitemaps.splice(_idx, 1, _sm);
            }
        }
        var _db = {'sitemaps':_sitemaps}
        chrome.storage.local.set(_db, function(){
            alert(chrome.i18n.getMessage('saved'));
        });
    })
}

function deleteSitemap(id){
    chrome.storage.local.get("sitemaps", function(db){
        var _sitemaps = db["sitemaps"];
        var index = _sitemaps.findIndex(function(s){return s.id == id})
        _sitemaps.splice(index, 1);
        var _db = {'sitemaps':_sitemaps}
        chrome.storage.local.set(_db, function(){
            alert(chrome.i18n.getMessage('deleted'));
        });
    })
}

function injectScript(tabId){
    var flag;
    chrome.tabs.sendMessage(tabId, {
        cmd: 'SELF_CHECK'
    }, function(r){
        flag = r;
    });
    setTimeout(function(){
        if(flag){
            chrome.tabs.executeScript(tabId, {file: "injected/define/initUI.js"}, function() {});
        }else{
            doInjectScript(tabId);
        }
    }, 200)
}

//Injected scripts will be removed once the tab reload again.
function doInjectScript(tabId){
    chrome.tabs.executeScript(tabId, {file: "injected/listener.js"});
    chrome.tabs.executeScript(tabId, {file: "lib/jquery/jquery-2.1.1.min.js"}, function() {
        chrome.tabs.executeScript(tabId, {file: "lib/model.js"});
        chrome.tabs.executeScript(tabId, {file: "lib/css-selector-generator.js"}, function() {});
        chrome.tabs.executeScript(tabId, {file: "injected/SelectTool.js"}, function() {});
        chrome.tabs.executeScript(tabId, {file: "injected/define/initUI.js"}, function() {});
        chrome.tabs.insertCSS(tabId, {file: "injected/injected.css", runAt: "document_end"});
    });
}


function createResultTab(title, fields, data){
    chrome.tabs.create({url: chrome.extension.getURL('result/table.html')}, function(newTab){
        var tabId = newTab.id;
        setTimeout(function(){
            chrome.tabs.sendMessage(tabId, {
                cmd: 'RESULT',
                params:{
                    data: data,
                    title: title,
                    fields: fields
                }
            });
        }, 200)
    })
}
提前感谢您的帮助。

我在中找到了答案。 如果我们将persistent=false设置为false,则后台js将在空闲时卸载

{
  "name": "My extension",
  ...
  "background": {
    "scripts": ["eventPage.js"],
    "persistent": false
  },
  ...
}
该文档告知从内容脚本发送消息将导致后台js重新加载。但我猜弹出脚本中的消息有问题


因此,在弹出窗口中更改persistenttruechrome.runtime.getBackgroundPage以导致后台js重新加载将解决此问题。

在没有看到doInjectScript代码的情况下,我猜这并不能解释执行chrome.tabs.create回调但选项卡尚未启动的情况正在加载URL。请选择主题中的问题:包括与问题重复的完整内容。包括manifest.json、一些后台/内容/弹出脚本/HTML。寻求调试帮助的问题(“为什么此代码不工作?”)必须包括:►想要的行为,►特定的问题或错误,以及►在问题本身中复制它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:“如何创建”和。谢谢wOxxOm。我认为您不应该关心doInjectScript代码,因为代码“alert(“Start to render”);”只是在“警报(“开始发送消息”);”之后不执行已执行。我已发布background.js的所有代码。我认为background.js代码将加载到chrome中,并且在chrome关闭之前不会回收。但似乎我错了。我在第一行添加了“alert('loaded background.js'),它会在几分钟后偶尔发出警报。不要使用
alert
,它是一个古老的垃圾,正在被弃用/删除。使用devtools正确调试后台页面。事件页面的消息发布本身应该成功,因此根本原因可能仍在代码中。