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

标签 javascript google-chrome google-chrome-extension

我写了一个chrome扩展,popup js会发消息给后台,后台会把消息重定向到content script,经过一些网络请求,结果应该返回给后台,然后popup js。

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

弹出js

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

后台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;
});

如果我将消息隧道更改为 the Long-lived connections , 它会起作用,为什么?

最佳答案

@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;
});

而且我可以直接从弹出窗口向内容脚本发送消息。

关于javascript - 内容脚本向后台发送响应时获取 "Could not establish connection. Receiving end does not exist.",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47066984/

相关文章:

css - 在 Chrome 中检查元素时空白消失

html - Safari 不承认 "required"属性。如何解决?

javascript - chrome 扩展 chrome.storage 如何同时进行大量获取和设置并避免竞争条件?

javascript - Java 和 Chrome 扩展、本地消息

javascript - WebStorm 错误 : expression statement is not assignment or call

javascript - 如何确定 if::before 应用于元素?

google-chrome - Chrome API 响应 header

javascript - 页面行为修改谷歌浏览器扩展?

javascript - 如何显示 Redactor 富文本/html 编辑器的字符数/字数?

javascript - 使用纯 CSS 的样式范围输入作为图像之间的分隔