Chrome扩展程序中的jQuery.ajax调用失败

时间:2009-12-23 20:40:34

标签: javascript jquery google-chrome google-chrome-extension

我正在将我的一个Firefox扩展程序移植到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问题),如果是图像网址,它会发送一个HEAD请求并检查“Content-Type”响应标头以确保这是一张图片。如果是这样,它将返回true,将剪贴板文本粘贴到IMG标记中。否则,如果它看起来像是不是图像的普通URL,则将其包装在A标记中。如果它不是URL,则只进行普通粘贴。

无论如何,被检查的url肯定是一个图像,并且在FF中工作正常,但在完整的函数中,xhr.status为“0”,当函数完成时状态为“error”。将超时提升至10秒无济于事。我已经验证测试图像在运行时应该以“image / jpeg”的形式返回:

curl -i -X HEAD <imageURL>

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

4 个答案:

答案 0 :(得分:11)

当您在内容脚本中找到Chris时,您无法执行任何跨域XHR。您必须在扩展页面(例如“背景”,“弹出窗口”或甚至“选项”)中执行此操作。

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

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

答案 1 :(得分:5)

检查您的清单文件。扩展程序是否有权访问该网址?

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

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请求的响应传递回您的内容脚本,并在那里做任何您想做的事情。

答案 2 :(得分:5)

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

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

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

另一个问题是Chrome确实阻止了content_scripts部分中的任何内容进行AJAX调用,而是无声地失败。但是,如果你有一个对background_page没有这样的限制。该页面可以进行任何所需的AJAX调用,Chrome有一个API,允许您的脚本打开一个端口并将请求传递给该后台页面。有人写了一个名为XHRProxy的脚本作为解决方法,我修改它以获得适当的响应头。它有效!

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

答案 3 :(得分:2)

接受的答案已过时。

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.