【问题标题】:jQuery.ajax call fails inside Chrome extensionjQuery.ajax 调用在 Chrome 扩展中失败
【发布时间】:2009-12-23 20:40:33
【问题描述】:

我正在将我的一个 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”,函数完成时状态为“error”。将超时时间增加到 10 秒并没有帮助。我已经验证测试图像在运行时应该返回为“image/jpeg”:

curl -i -X HEAD <imageURL>

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

【问题讨论】:

  • 可能是对所有来自扩展的 AJAX 请求的安全限制吗?
  • 不应该return isImage; 是完整回调的一部分吗?
  • @pixieline:可以。那只是有一个返回点,但它甚至没有走那么远,因为 switch(status) 是“错误”,因此永远不会调用该分支。
  • @Ivan:我打赌这就是问题所在,但除了 alert() 调用之外,我还没有想出登录 Chrome,所以我不确定它是静默失败还是有其他一些问题。 xhr.responseText 也是空白的。
  • 你确定type: "HEAD" 吗?文档说它应该是 GET 或 POST,其他是允许的,但并非所有浏览器都支持。可能就是这种情况,因为它在 FF 中有效,但在 chrome 中无效。

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


【解决方案1】:

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

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

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

【讨论】:

【解决方案2】:

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

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

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

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

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

【讨论】:

  • 嘿,这个不成立了,内容脚本现在可以发出xml请求了,看我的回答。
【解决方案3】:

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

【讨论】:

  • 这是问题之一。另一个是 content_scripts 不能发送 AJAX 请求。但是,背景页面可以,我将在我自己的答案中解释。
【解决方案4】:

接受的答案已过时。

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.

【讨论】:

    猜你喜欢
    • 2011-10-11
    • 1970-01-01
    • 2014-12-20
    • 1970-01-01
    • 1970-01-01
    • 2020-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多