Chrome扩展消息传递:未发送响应
Chrome Extension Message passing: response not sent
我正在尝试在内容脚本和扩展之间传递消息
以下是我在内容脚本中的内容
chrome.runtime.sendMessage({type: "getUrls"}, function(response) {
console.log(response)
});
在后台脚本中,我有
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.type == "getUrls"){
getUrls(request, sender, sendResponse)
}
});
function getUrls(request, sender, sendResponse){
var resp = sendResponse;
$.ajax({
url: "http://localhost:3000/urls",
method: 'GET',
success: function(d){
resp({urls: d})
}
});
}
现在,如果我在getUrls
函数中的ajax调用之前发送响应,则响应发送成功,但在ajax调用的成功方法中,当我发送响应时,它没有发送响应,当我进行调试时,我可以看到sendResponse
函数的代码中的端口为空。
来自chrome.runtime.onMessage.addListener
:的文档
如果要异步使用sendResponse(),请添加return true;到onMessage事件处理程序。
因此,您只需要在对getUrls
的调用之后添加return true;
,以表明您将异步调用响应函数。
请注意,其他文档(例如onMessage
文档)中没有提到这一点,因此开发人员可能会错过这一点。
接受的答案是正确的,我只是想添加简化这一点的示例代码。问题是API(在我看来)设计得不好,因为它迫使我们的开发人员知道是否将异步处理特定的消息。如果您处理许多不同的消息,这将成为一项不可能完成的任务,因为您永远不知道传递给sendResponse的某个函数是否会被称为async。考虑一下:
chrome.extension.onMessage.addListener(function (request, sender, sendResponseParam) {
if (request.method == "method1") {
handleMethod1(sendResponse);
}
我如何知道handleMethod1
的深层调用是否是异步的?修改handleMethod1
的人怎么知道它会通过引入异步来破坏调用者呢?
我的解决方案是:
chrome.extension.onMessage.addListener(function (request, sender, sendResponseParam) {
var responseStatus = { bCalled: false };
function sendResponse(obj) { //dummy wrapper to deal with exceptions and detect async
try {
sendResponseParam(obj);
} catch (e) {
//error handling
}
responseStatus.bCalled= true;
}
if (request.method == "method1") {
handleMethod1(sendResponse);
}
else if (request.method == "method2") {
handleMethod2(sendResponse);
}
...
if (!responseStatus.bCalled) { //if its set, the call wasn't async, else it is.
return true;
}
});
无论您选择如何处理消息,这都会自动处理返回值。请注意,这假设您永远不会忘记调用响应函数。还要注意,铬本可以为我们自动化,我不明白他们为什么没有。
您可以使用我的库https://github.com/lawlietmester/webextension让这在Chrome和FF中与Firefox一起工作,而不需要回调。
你的代码看起来像:
Browser.runtime.onMessage.addListener( request => new Promise( resolve => {
if( !request || typeof request !== 'object' || request.type !== "getUrls" ) return;
$.ajax({
'url': "http://localhost:3000/urls",
'method': 'GET'
}).then( urls => { resolve({ urls }); });
}) );
- 可以't添加Chrome扩展的响应标头
- Chrome扩展消息传递:未发送响应
- 来自 chrome 扩展程序中内容脚本的未定义响应
- Firefox 扩展损坏了 gzip 响应
- 未发送 Chrome 扩展程序发送响应回调值
- 如何创建在引导程序 3 中也可以纵向扩展的响应式映像
- Http 响应标头在火狐扩展中总是不会被修改
- Chrome扩展-如何获取HTTP响应正文
- 在Express和Node.js中,是否可以扩展或覆盖响应对象的方法
- 在Firefox Web扩展中使用chrome.runtime.sendMessage不会产生响应
- 使用Chrome扩展修改HTTP请求的响应主体
- jquery-datatables-rails.响应式扩展和移动视图
- 在响应式设计中禁用Javascript扩展器
- 数据表列可见性与响应扩展
- Chrome扩展运行时.Sendmessage等待响应
- Firefox扩展:取消请求并发出假响应
- 响应扩展-隐藏所有列,但第一个
- XMLHttpRequest POST响应通过JSON总是空(Chrome扩展)
- Chrome扩展:如何响应从"弹出"在内容脚本中
- 响应自定义扩展预览