9

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

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

curl -i -X HEAD <imageURL>

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

4

4 回答 4

11

正如您所了解的 Chris,在内容脚本中,您不能执行任何跨域 XHR。您必须在诸如背景、弹出窗口甚至选项的扩展页面中执行它们。

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

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

于 2009-12-24T20:11:31.773 回答
6

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

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

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

另一个问题是 Chrome 确实阻止 content_scripts 部分中的任何内容进行 AJAX 调用,静默失败。但是,如果您有 background_page,则没有这样的限制。该页面可以进行任何它想要的 AJAX 调用,并且 Chrome 有一个 API 允许您的脚本打开一个端口并将请求传递到该背景页面。有人编写了一个名为XHRProxy的脚本作为解决方法,我对其进行了修改以获取适当的响应标头。有用!

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

于 2009-12-24T15:10:30.913 回答
5

检查您的清单文件。扩展程序是否有权访问该 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 请求的响应传递回您的内容脚本,并在那里做任何您想做的事情。

于 2009-12-23T22:53:20.037 回答
2

接受的答案已过时。

内容脚本现在可以像后台脚本一样生成跨站点 XMLHttpRequest!

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

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

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

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

以获得更一般的权限。

这是文档的链接。

于 2013-09-11T16:14:50.803 回答