using a named function as the callback for $.getJSON in jQuery to satisfy Facebook request signing demands

StackOverflow https://stackoverflow.com/questions/203194

Question

I'm trying to access the Facebook API Admin.getMetrics method via jQuery. I'm correctly composing the request url on the server side (in order to keep my app secret secret). I'm then sending the url over to the browser to be request using jQuery.getJSON().

Facebook requires that I send a copy of all of my request params hashed with my application secret along with the request in order to verify my authenticity. The problem is that jQuery wants to generate the name of the callback function itself in order to match the name it gives to the anonymous function you pass in to be called when the data returns. Therefore, the name of the function is not available until jQuery.getJSON() executes and Facebook considers my request to be inauthentic due to a mismatched signature (the signature I send along does not include the correct callback param because that was not generated until jQuery.getJSON() ran).

The only way I can think of out of this problem is to somehow specify the name of my function to jQuery.getJSON() instead of allowing it to remain anonymous. But I cannot find any option for doing so in the jQuery AP.

Was it helpful?

Solution 2

The use of jQuery.getScript turned out to be close to -- but not quite -- the answer. Using getScript eliminates jQuery's need to add the dynamically named anonymous function to the request params (though it will still do that if you go ahead and pass it an anonymous function as in the above code). However, the default in jQuery.getScript, as in all the other calls in jQuery's Ajax library, is to append a further additional argument _=12344567 (where 1234567 is really a time stamp). jQuery does this to prevent the browser from caching the response. However, this additional breaks my signing of the request just like the auto-named callback function.

With some help on #jquery, I learned that the only way to get jQuery not to mess at all with your params is to make the request using the base jQuery.Ajax method with the following arguments:

jQuery.ajax({
  url: fbookUrl,
  dataType: "script",
  type: "GET",
  cache: true,
  callback: null,
  data: null
});

(where fbookUrl is the Facebook API url I'm trying to request with its full params including the signature and the callback=myFunction). The dataType: "script" arg specifies that the resulting JSONP should be stuffed into a script tag on the page for execution, cache: true tells jQuery to allow the browser to cache the response, i.e. to skip the addition of the time stamp parameter.

OTHER TIPS

The only thing that did the work for me were the following settings

jQuery.ajax({ url: fbookUrl, dataType: "jsonp", type: "GET", cache: true, jsonp: false, jsonpCallback: "MyFunctionName" //insert here your function name });

You can pass the JSONP option to $.ajaxSetup that will allow you to fix the function name that gets called, the docs read as follows:

jsonp String
Override the callback function name in a jsonp request. This value will be used instead of 'callback' in the 'callback=?' part of the query string in the url for a GET or the data for a POST. So {jsonp:'onJsonPLoad'} would result in 'onJsonPLoad=?' passed to the server.

See here http://docs.jquery.com/Ajax/jQuery.ajax#options for more details

This is a better solution with a fixed callback:

window.fixed_callback = function(data){
    alert(data.title);
};

$(function() {
    $.getScript("http://api.flickr.com/services/feeds/photos_public.gne?tags=cats&tagmode=any&format=json&jsoncallback=fixed_callback", function(data) {
    alert('done'); } );
});

The problem with this callback is you can only handle one kind of request at a time as the function is globally registered. The callback function would probably have to turn into a dispatcher for the different kinds of data that it could retrieve and call the appropriate function.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top