I think I'm going to be stuck writing a messy dispatch function, but thought I'd check the S.O. community first to see if someone has come up with an easier solution.
Bless the World Bank for having an open API, but they have some implementation problems. First problem is their server doesn't implement CORS Access-Control-Allow-Origin: *, so that means JSONP instead of JSON. That wouldn't be a problem, except that they don't preserve the case of the callback function! To cite a specific example, I make the following request in my code:
var deferredRegionsRequest = $.getJSON(
"http://api.worldbank.org/regions/?prefix=?",
{format: "jsonp"}
);
(Yes, they use the parameter prefix instead of the traditional callback.)
jQuery dutifully creates a random callback function and issues the AJAX request as:
http://api.worldbank.org/regions/?prefix=jQuery18308848262811079621_1393981029347&format=jsonp&_=1393981029990
Note that the callback function has an uppercase Q.
The response that the World Bank returns, however, has renamed that callback to all lowercase!
jquery18308848262811079621_1393981029347([
{ "page": "1", "pages": "1", "per_page": "50", "total": "32" },
[ {
"id": "",
"code": "AFR",
"name": "Africa"
}, {
...
Obviously that's not going to work. If I were just making a single request, it wouldn't be too painful to provide my own callback function and use the jsonpCallback parameter of $.ajax(). Unfortunately, I need to traverse and loop through their REST API, so I'll be making dozens of (parallel) API calls. I've checked a custom callback, and this is set to the global window object, so there doesn't seem to be any obvious way for a single callback function to manage multiple responses. It seems like I might be stuck with a messy, custom dispatcher implementation, which I'd really like to avoid.
The only alternative I've come up with so far is to define a beforeSend callback that takes the fully populated URL, parses it to find the callback function (jQuery...), creates a new callback function dynamically that's an all lowercase version of the original (jquery...), and does nothing by call the original. The hack quotient is so high my head spins, but I've verified that this does work:
$.ajaxSetup({
beforeSend: function(xhr, settings) {
var prefix = settings.url.match(/prefix=(.*?)&/);
if (prefix.length > 1) {
var callback = prefix[1];
if (callback !== callback.toLowerCase()) {
window[callback.toLowerCase()] =
new Function("response", callback + "(response)");
}
}
}
});
I sure hope I'm missing something really simple and someone very kind will point it out to me.