Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSONP request in chrome extension, callback function doesn't exist?

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);
    }
})
like image 681
Chris Sobolewski Avatar asked Dec 13 '11 20:12

Chris Sobolewski


People also ask

What is JSONP callback?

By Arsal Khan. March 1, 2022. JSON with Padding, or JSONP for short, is a technique that allows developers to get around browsers' same-origin policies by exploiting the nature of the <script> element.

What request does JSONP use?

JSONP works by constructing a “script” element (either in HTML markup or inserted into the DOM via JavaScript), which requests to a remote data service location.

How does JSONP request work?

Standard JSON Asynchronous requestThe browser makes an asynchronous POST request to the server slapping its parameters to the service in the body. The server responds with a string of JSON data. A success handler of the request fires and the string is converted into a Javascript Object to be used in the application.


1 Answers

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

like image 156
Adam Ayres Avatar answered Sep 30 '22 07:09

Adam Ayres