代码之家  ›  专栏  ›  技术社区  ›  Chris Doggett

jquery.ajax调用在chrome扩展内失败

  •  9
  • Chris Doggett  · 技术社区  · 16 年前

    我正在将我的一个火狐扩展移植到Chrome,我在Ajax查询中遇到了一个小问题。以下代码在FF扩展中工作正常,但在Chrome中失败,状态为“0”。

    function IsImage(url) {
        var isImage = false;
        var reImageContentType = /image\/(jpeg|pjpeg|gif|png|bmp)/i;
        var reLooksLikeImage = /\.(jpg|jpeg|gif|png|bmp)/i;
    
        if(!reLooksLikeImage.test(url)) 
        {
            return false;
        }
    
        var xhr = $.ajax({
            async: false,
            type: "HEAD",
            url: url,
            timeout: 1000,
            complete : function(xhr, status) {
                switch(status)
                {
                    case "success":
                        isImage = reImageContentType.test(xhr.getResponseHeader("Content-Type"));
                        break;
                }
            },
        });
    
        return isImage;
    }
    

    这个扩展的特定部分检查剪贴板上的内容(我已经解决的另一个chrome问题),如果它是图像URL,它会发送一个head请求并检查“content-type”响应头以确保它是图像。如果是这样,它将返回true,将剪贴板文本粘贴到img标记中。否则,如果它看起来像一个普通的URL,而不是一个图像,它将它包装在一个标签中。如果它不是一个URL,它只做一个简单的粘贴。

    无论如何,被检查的URL肯定是一个图像,在FF中工作正常,但是在完整的函数中,xhr.status是“0”,当函数完成时,status是“error”。把超时时间增加到10秒没有帮助。我已经验证了运行时测试图像应返回为“image/jpeg”:

    curl -i -X HEAD <imageURL>
    

    我也知道我应该使用成功和错误回调,而不是完全回调,但它们也不起作用。有什么想法吗?

    4 回复  |  直到 12 年前
        1
  •  11
  •   Mohamed Mansour    16 年前

    正如您发现的,在内容脚本中,不能执行任何跨域XHR。您必须在扩展页面中执行这些操作,例如后台、弹出窗口,甚至是选项。

    有关内容脚本限制的详细信息,请参阅: http://code.google.com/chrome/extensions/content_scripts.html

    有关xhr限制的更多信息,请参阅: http://code.google.com/chrome/extensions/xhr.html

        2
  •  5
  •   Chris Doggett    16 年前

    我已经解决了部分问题,实际上大部分问题。首先,正如布伦南和我昨天提到的,我需要在manifest.json中设置权限。

    "permissions": [
        "http://*/*",
        "https://*/*"
    ],
    

    为每个域授予权限并不理想,但是由于可以从任何域承载图像,因此必须这样做,而且我必须防范XSS。

    另一个问题是,Chrome确实阻止了Content-Scripts部分中的任何内容进行Ajax调用,并无声地失败。但是,如果您有后台页面,则不存在这样的限制。这个页面可以进行它想要的任何Ajax调用,而chrome有一个API,允许脚本打开一个端口并将请求传递到后台页面。有人写了一个脚本 XHRProxy 作为解决方法,我修改了它以获得适当的响应头。它起作用了!

    我现在唯一的问题是如何让脚本等待调用结果在事件中设置,而不是立即返回。

        3
  •  5
  •   Brennan McEachran    16 年前

    检查您的清单文件。扩展是否具有访问该URL的权限?

    如果它对您的第二个问题(或其他任何问题)有帮助: 您可以向后台页面发送请求,如下所示:

    chrome.extension.sendRequest({var1: "var1value", var2: "value", etc}, 
     function(response) {
        //Do something once the request is done.
    }); 
    

    变量 response 可以是任何你想要的。它可以只是一个成功或拒绝字符串。由你决定。

    在后台页面上,您可以添加一个侦听器:

    chrome.extension.onRequest.addListener(
    function(request, sender, sendResponse) {
          // Do something here
          // Once done you can send back all the info via:
          sendResponse( anything you want here );
    
          // and it'll be passed back to your content script.
    });
    

    通过这个,您可以将来自Ajax请求的响应传递回内容脚本,并在那里做任何您想做的事情。

        4
  •  2
  •   Konstantin Schubert    12 年前

    公认的答案过时了。

    Content scripts can now make cross-site XMLHttpRequests just like background scripts!

    清单中需要允许相关的URL:

    {
      "name": "My extension",
      ...
      "permissions": [
        "http://www.google.com/"
      ],
      ...
    }
    

    您还可以使用以下表达式:

    "http://*.google.com/"
    "http://*/"
    

    以获取更多常规权限。

    Here is the Link to the documentation.