【发布时间】:2019-06-08 10:54:11
【问题描述】:
我的 chrome 扩展有以下两个 javascript:
background.js,作为后台脚本运行:
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
if (message.data == "takeScreenshot") {
var resp = sendResponse;
chrome.tabs.captureVisibleTab(function(screenshotUrl) {
resp({
screenshot: screenshotUrl
});
});
return true; // Return true to tell that the response is sent asynchronously
} else {
return "TestReply";
}
});
api.js,作为网络可访问资源运行:
window.takeScreenshot = (function() {
var isTakingScreenshot = false; // Semaphore
return function() {
if(isTakingScreenshot) return Promise.reject();
isTakingScreenshot = true;
return new Promise(function(resolve, reject) {
chrome.runtime.sendMessage("eomfljlchjpefnempfimgminjnegpjod", "takeScreenshot", function(response) {
console.log(response);
isTakingScreenshot = false;
resolve(response.screenshot);
});
});
}
})()
window.test = (function() {
return function() {
return new Promise(function(resolve, reject) {
chrome.runtime.sendMessage("eomfljlchjpefnempfimgminjnegpjod", "test", function(response) {
console.log(response);
resolve(response.length);
});
});
}
})();
当我在选项卡的控制台中执行任一功能时(自动完成功能知道它们,因此它们可用),我收到错误:
未经检查的 runtime.lastError:无法建立连接。接收端不存在。
并且返回的响应是未定义的。
我检查了sendMessage 中的 id 是否与清单和 chrome://extensions 页面中的相同,并且我已经打开了扩展程序的后台页面 DevTools 并在那里手动添加了相同的侦听器来制作确保侦听器确实已注册。
我的搜索发现这个错误意味着监听器没有正确注册,但我没有找到根本原因。您知道导致此错误的原因吗?
【问题讨论】:
-
由于您使用的是 web_accessible_resource,因此您必须将其作为无法访问扩展环境的页面脚本运行 - 您需要通过 externally_connectable 键公开消息。
-
@wOxxOm 你能解释一下
externally_connectable与一般permissions有何不同吗?在不了解externally_connectable设置的情况下,我似乎能够多年来毫无问题地使用chrome.runtime.sendMessage()和chrome.runtime.onMessage.addListener()。 -
@Atav32,我看不出你的评论与问题和我的评论有何关联,所以我无法回答,但我猜你没有运行页面脚本。
-
我们遇到了同样的错误,我们没有尝试与外部扩展通信。我在下面有一个非最佳解决方案。也许@wOxxOm 有更好的主意。在调用 connect 之前,没有其他 api 可以检查端口是否已经被监听。
-
嗨@wOxxOm - 我做了一个最小的扩展来向你展示这个问题。如果您只是加载此扩展程序,您将收到错误“未检查的 runtime.lastError:无法建立连接。接收端不存在。”但是如果您打开弹出窗口然后重新加载内容脚本,问题就会消失。 github.com/ddehghan/bugReproExtension 。内容脚本如何确保连接前有监听器。这似乎是一个错误。