获取内容脚本发送时"Could not establish connection. Receiving end does not exist."对后台的响应



我写了一个chrome扩展,弹出js会向后台发送一条消息,后台会将消息重定向到内容脚本,经过一些网络请求,结果应该返回到后台然后弹出js。

下面是我的一些简化的代码片段。

弹出式 JS

$('.porintButton').click(function() {
    switch (this.id) {
        case 'learningPointButton':
            chrome.runtime.sendMessage({ action: 'learning' }, callback);
            processResult();
            break;
    }
    return true;
});

Backgound JS的

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
        chrome.tabs.sendMessage(tabs[0].id, request, response => {
            if (chrome.runtime.lastError) {
                // If I click learningPointButton, the line will excute, and log 'ERROR:  {message: "Could not establish connection. Receiving end does not exist."}' 
                console.log('ERROR: ', chrome.runtime.lastError);
            } else {
                console.log('The Content Script got the following Message: ' + JSON.stringify(response));
                sendResponse(response);
            }
        });
    });
    return true;
});

内容脚本

chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
    console.info('contentscript', request, sender);
    switch (request.action) {
        case 'learning':
            // this simulate network async request, will not work, 
            setTimeout(() => {
                sendResponse({ action: request.action, result: 'ok' });
            }, 0);
            // this works
            // sendResponse({ action: request.action, result: 'ok' });
            break;
    }
    // I have read https://developer.chrome.com/extensions/messaging#simple and return true here
    return true;
});

如果我将消息隧道更改为长期连接,它将起作用,为什么?

@wOxxO 谢谢,你是对的。

我使用 Promise 样式重写了代码,它现在可以工作了。

我像这样重写的代码。

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    console.info('contentscript', request, sender);
    switch (request.action) {
        case 'learning':
            Promise.all([doLearning(), doLearning(), doLearning()])
                .then(unusedData => {
                    return getScore();
                })
                .then(scores => {
                    console.info(scores);
                    sendResponse({ action: request.action, result: 'ok', scores: scores });
                })
                .catch(e => {
                    console.error(e);
                    sendResponse({ action: request.action, result: 'error', message: e });
                });
            break;
        case 'score':
            getScore().then(scores => {
                console.info(scores);
                sendResponse({ action: request.action, result: 'ok', scores: scores });
            }).catch(e => {
                console.error(e);
                sendResponse({ action: request.action, result: 'error', message: e });
            });
            break;
    }
    return true;
});

我可以直接将消息从弹出窗口发送到内容脚本。

相关内容

最新更新