代码之家  ›  专栏  ›  技术社区  ›  Bambax

Chrome扩展消息传递,当jQuery中的xhr调用失败时

  •  1
  • Bambax  · 技术社区  · 14 年前

    我正在Google Chrome中构建一个扩展,它可以对网站进行查询。

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

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

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

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

    搜索此错误只会检索找到此文本的Chrome的源代码,因此没有太大帮助。

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

    2 回复  |  直到 14 年前
        1
  •  1
  •   npdoty    14 年前

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

    • 异步响应 :您可以立即向内容脚本发送空响应,然后稍后启动与内容脚本的新连接以发送响应。内容脚本需要为消息添加侦听器。显然,如果您要发出多个这样的请求,您将需要一些令牌来回传递,以便您可以将响应与它们的原始请求匹配起来。
    • 使用 $.ajax() :这允许您内联指定成功回调和错误回调;如果您可以成功 发送响应 从成功回调,您还应该能够从错误回调。
    • 打造长寿港 : long-living connections 允许您随时向内容脚本发送消息。

    我也希望你能打电话给我 发送响应 从一个完全独立的函数 发送响应 函数,以便错误处理程序可以访问它,但也许您已经证明了这一点(希望看到您的代码)。文档使请求在被响应之前听起来像是打开的。

        2
  •  0
  •   Bambax    14 年前

    在查看代码以确定是否可以提取其中的一些代码来构建一个工作示例(响应serg注释)之后,我认为我不想用jQuery做什么。

    在jQuery中,当ajax调用失败时,会调用一个错误事件(使它被.ajax error()事件处理程序捕获),然后函数结束/返回。当.ajaxError()处理程序运行时,函数将因此失效。(我认为,这是JS中异步事件系统的全部要点)。

    现在,我只是猜测一下,但我认为在Chrome中,当listener函数运行时,内容脚本和后台脚本之间的通信通道是关闭的;在listener函数结束后,不能从后台脚本向内容脚本发送响应,这就是我在处理事件处理程序中的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);
        }