Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/401.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 获得;无法建立连接。接收端不存在。”;当内容脚本向后台发送响应时_Javascript_Google Chrome_Google Chrome Extension - Fatal编程技术网

Javascript 获得;无法建立连接。接收端不存在。”;当内容脚本向后台发送响应时

Javascript 获得;无法建立连接。接收端不存在。”;当内容脚本向后台发送响应时,javascript,google-chrome,google-chrome-extension,Javascript,Google Chrome,Google Chrome Extension,我写了一个chrome扩展,PopupJS将发送一条消息到后台,后台将消息重定向到内容脚本,在一些网络请求之后,结果应该返回到后台,然后PopupJS 下面是我的一些简化代码 弹出式js $('.porintButton').click(function() { switch (this.id) { case 'learningPointButton': chrome.runtime.sendMessage({ action: 'learning'

我写了一个chrome扩展,PopupJS将发送一条消息到后台,后台将消息重定向到内容脚本,在一些网络请求之后,结果应该返回到后台,然后PopupJS

下面是我的一些简化代码

弹出式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;
});

我可以从弹出窗口直接将消息发送到contentscript。

1。为什么要通过后台页面发送消息,而不是直接发送到内容脚本?2.您看到网页控制台中的错误了吗?代码中的哪一行生成错误?3。为什么
addListener(async
?回调不是一个异步函数。在后台删除
async
@wOxxOm第6行会生成错误。这是因为
async
返回一个承诺,而chrome API不能有效地处理承诺。您的内容脚本没有侦听器,这就是错误所说的。删除
async
>关键字。@wOxxOm chrome扩展有限制,它不能从弹出窗口向内容脚本发送消息,只能从后台中继。