【问题标题】:Chrome extension message passing, when xhr call fails in jQuery当 jQuery 中的 xhr 调用失败时,Chrome 扩展消息传递
【发布时间】:2010-11-15 14:40:10
【问题描述】:

我正在 Google Chrome 中构建一个针对网站发出查询的扩展程序。

查询由“背景页面”根据“内容脚本”的请求发出;当后台页面接收到发出查询的请求时,它会将查询发送出去,解析响应并将响应发送回内容脚本,使用 sendResponse()。

使用 XMLHttpRequest() 时一切正常;但我的问题是,如果我想使用 jQuery .get() 或 .load() 发出查询,那么当查询失败时,它们会静默失败,并且永远不会将响应发送到内容脚本。

如果我使用 .ajaxError() 注册事件处理程序,则会捕获错误,但显然无法从该事件处理程序调用 sendResponse(),因为我收到以下 Chrome 错误:

“尝试使用断开连接的端口对象”

搜索此错误只会检索找到此文本的 Chrome 的源代码,因此它不是很有帮助。

简而言之,我的问题是:是否可以在 Chrome 扩展的后台脚本中使用 jQuery.get(),并且在请求失败时仍然能够向内容脚本发送响应? (如果是,如何)

【问题讨论】:

  • 你能贴一些代码吗?

标签: jquery google-chrome-extension


【解决方案1】:

如果没有代码示例,这很难直接解决(您是如何将 sendResponse 传递给错误处理程序的?),但我认为有一些替代方法可以自己构建 XHR。

  • 异步响应:您可以立即向内容脚本发送一个空响应,然后再启动到内容脚本的新连接以发送响应。内容脚本将需要为消息添加侦听器。显然,如果您要发出多个此类请求,您会希望来回传递一些令牌,以便您可以将响应与它们的原始请求相匹配。
  • 使用$.ajax():这允许您内联指定成功和错误回调;如果你可以从成功回调中成功sendResponse,你应该也可以从错误回调中。
  • 创建长寿命端口long-living connections 让您随时向内容脚本发布消息。

我还想认为,如果您存储了 sendResponse 函数以便错误处理程序可以访问它,那么您可以从一个完全独立的函数中调用 sendResponse,但也许您已经证明了这个错误(很想看到你的代码)。该文档听起来像是请求在得到响应之前是开放的。

【讨论】:

  • 你是对的,使用 $.ajax() 可以指定一个错误回调函数;但它可能比我简单的 XHR 函数复杂一点。此外,我在后台脚本中包含 jQuery 的唯一原因就是这个;使用我自己的 XHR 函数,我什至不再需要在后台页面中使用 jQuery。
【解决方案2】:

在查看了代码以查看是否可以提取其中的一些来构建一个工作示例(响应 serg 评论)之后,我认为使用 jQuery 无法实现我想要做的事情。

在 jQuery 中,当 ajax 调用失败时,会调用错误事件(以便被 .ajaxError() 事件处理程序捕获),然后函数结束/返回。当 .ajaxError() 处理程序运行时,该函数因此死了。 (我相信,这就是 JS 中异步事件系统的全部意义所在)。

现在,我只是在这里猜测,但我认为在 Chrome 中,当侦听器函数运行时,内容脚本和后台脚本之间的通信通道是关闭的;在侦听器函数结束后,无法从后台脚本向内容脚本发送响应,这是我在事件处理程序中处理 ajax 错误时尝试做的。

所以,我最终做的是重新实现一个 ajax 函数,该函数实际上会返回一个完整的对象:如果调用失败,它会返回发生错误的事实以及错误代码,以便调用者函数(实际上是回调)可以处理它并将响应发送回内容脚本。

只有几行,而且(我认为)很笼统,所以这里是:

function xhr(url, callback) {
    var req = new XMLHttpRequest();
    req.open("GET", url, true);
    req.onreadystatechange = function() {
        if (req.readyState == 4) {
            var resp = {
                "url": url,
                "status": req.status
                };
            if (req.status == 200) {
                resp.html = req.responseText;
                resp.outcome = "ok";
                }
            else {
                resp.outcome = "error";
                }
            callback(resp);
            }
        }
    req.send(null);
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-01
    • 1970-01-01
    • 2021-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多