JSONP request in chrome extension, callback functi

2019-01-09 03:36发布

问题:

I am making a JSONP request in a chrome extension (content script) . Everything works very well when I am running as a webpage -loading the HTML file in my browser-, but when I load it as a chrome extension, the jsonp callback function created by jquery doesn't seem to exist when the server gives its response.

My console says:

Uncaught ReferenceError: jQuery17105683612572029233_1323808231542 is not defined

Here is my ajax request:

$.ajax({
    url: 'http://example.com',
    data: 
    {
        imgUrl: this.href,
        returnString:true
    },
    dataType: "jsonp",
    success: function(msg){
        newNode.src = msg.data;
    },
    error: function(msg){
        console.log(msg.data);
    }
})

回答1:

The issue is that the JSONP response is being caught by the actual page, outside of the sandboxed JavaScript code that the Chrome content script limits you too.

jQuery17105683612572029233_1323808231542 is the name of the callback function that the jQuery JSONP call has dynamically generated for the specific call. This function is being defined in the sandboxed area the content script has access to.

The only workaround that I am aware of, which worked for me, is to make an XHR call from the content script. As of Chrome 13 you can make XHR calls cross-domain from the content scripts (pretty cool). In your manifest file you need to add the external URL to the permissions:

{
    ...
    "permissions": [
        "http://example.com"
    ]
}

You can then make the XHR call like so:

var xhr = new XMLHttpRequest();
xhr.open("GET", "http://example.com/", true);
xhr.onreadystatechange = function() {
    if (xhr.readyState == 4) {
       //handle the xhr response here
  }
}
xhr.send();

You will need to do some of the things that jQuery was doing automatically for you, like encoding the values of the data object into the XHR URL (in your case the "imrUrl" and "returnString") as well as convert the response from the xhr.responeText or xhr.reponseXML into an object.

The downside of this approach is that if you are sharing this code between a Chrome extension and something else (like a bookmarklet) you now have to have different logic for the Chrome use case.

For more info see: Chrome Extension XHR