tags:

views:

35

answers:

1

This whole jsonp thing is quite confusing...

Here is what I want to do:

  • I have a class DataRetriever
  • The class has a method GetData
  • GetData makes a jsonp request with the following code:

    var new_tag = document.createElement('script');
    new_tag.type = 'text/javascript';
    new_tag.src = 'http://somesite.com/somemethod?somedata';
    // Add the element
    var bodyRef = document.getElementsByTagName("body").item(0);
    bodyRef.appendChild(new_tag);
    

Now, the jsonp data from the server somesite.com can call a function in my code with the data. The problem is, how does the data get delivered to the instance of DataRetriever that requested it?

I'm really stuck here.

+2  A: 

The solution jQuery came up with, is to provide an anonymous callback function like this:

jQuery.getJSON("http://mycrossdomain.com/?callback=?", function(data) {
   // Now I have the data
});

I think this could be adapted to your case as well.

var data = new DataRetriever();
data.GetData(function(data) {
    // Now I have the data 
});

You could do the same thing behind the scenes in the GetData function if you didn't want to provide an anonymous function.

function GetData(callback) { // optional
    // Create random function name however you want
    var funcName = "data_" + (+new Date() + Math.floor(Math.random()*100)),
        // Moved this up to be available in the random function
        new_tag = document.createElement('script');
    // This part will allow you to do the callback behind the scenes if callback isn't provided as a param
    callback = callback || function(data) {
        this.dataReturned = data; // or something
    }
    // Assign it to the window object
    window[funcName] = function(data) {
         callback(data);
         // Unassign this function
         delete window[funcName];
         // Recycle the script tag
         document.body.removeChild(new_tag);
    }
    new_tag.type = 'text/javascript';
    new_tag.src = 'http://somesite.com/somemethod?callback='+funcName;
    // Add the element
    document.body.appendChild(new_tag);
 }

Note you will have to make sure the JSONP request accepts the callback GET parameter. If you're using a 3rd party API they will already support this. Hope this helps!

lark
You should probably round/floor/ceil that random value as function names shouldn't have `.` in them.
Delan Azabani
Excellent point, I should also note that I would not suggest using my method of function name randomization. Perhaps something like:var funcName = "data_" + (+new Date()) + Math.floor(Math.random()*100);would be more suitable.
lark
Excellent! Thank you very much!
George Edison