开发者

jQuery.ajax call fails inside Chrome extension

I'm porting one of my Firefox extensions to Chrome, and I'm running into a little problem with an AJAX query. The following code works fine in the FF extension, but fails with a status of "0" in Chrome.

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;
}

This particular part of the extension checks what's on the clipboard (another Chrome issue I've already solved), and if it's an image URL, it sends a HEAD request and checks the "Content-Type" response header to be sure it's an image. If so, it'll return true, pasting the clipboard text in a开发者_开发百科n IMG tag. Otherwise, if it looks like a normal URL that's not an image, it wraps it in an A tag. If it's not a URL, it just does a plain paste.

Anyway, the url being checked is definitely an image, and works fine in FF, but in the complete function, xhr.status is "0", and status is "error" when the function completes. Upping the timeout to 10 seconds doesn't help. I've verified the test images should come back as "image/jpeg" when running:

curl -i -X HEAD <imageURL>

I also know I should be using the success and error callbacks instead of complete, but they don't work either. Any ideas?


As you figured out Chris, in Content Scripts, you can't do any Cross-Domain XHRs. You would have to do them in an extension page such as Background, Popup, or even Options to do it.

For more information regarding content script limitation, please refer to: http://code.google.com/chrome/extensions/content_scripts.html

And for more information regarding xhr limitation, please refer to: http://code.google.com/chrome/extensions/xhr.html


I've solved part of the problem, actually most of it. First, as Brennan and I mentioned yesterday, I needed to set permissions in manifest.json.

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

It's not ideal to give permissions to every domain, but since images can be hosted from any domain, it'll have to do, and I'll have to guard against XSS.

The other problem is that Chrome indeed blocks anything in the content_scripts section from making AJAX calls, failing silently. However, there is no such restriction on the background_page, if you have one. That page can make any AJAX calls it wants, and Chrome has an API to allow your script to open a port and pass requests to that background page. Someone wrote a script called XHRProxy as a workaround, and I modified it to get the appropriate response header. It works!

My only problem now is figuring out how to make the script wait for the result of the call to be set in the event, instead of just returning immediately.


Check your manifest file. Does the extension have permission to access that url?

If it helps to your second problem (or anyone else): You can send a request to your background page like:

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

The Variable response can be anything you want it to be. It can simply be a success or deny string. Up to you.

On your background page you can add a listener:

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.
});

With this you can pass the response from your AJAX request back to your content script and do whatever you wanted to do with it there.


The accepted answer is outdated.

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

The concerning URLs need to be permitted in the manifest:

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

You can also use expressions like:

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

to get more general permissions.

Here is the Link to the documentation.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜