Reputation: 29985
I was wondering whether my approach to JSONP is correct and if not, what I can change.
My standard JSONP approach:
Server
Standard ?jsonp=callback parameter
Client
<script>
tag *2Code
Note: I just wrote all of these in the stackoverflow editor, code is untested
1:
jsonp("http://example.com/sampleAPI", function(result) {
// Do something
});
2:
var callbackID = 0;
var jsonp = function(url, callback) {
var callbackName = 'callback' + callbackID;
// put the callback in the URL
callbackID++;
if (url.indexOf('?') != -1) {
url += '&jsonp=' + callbackName;
} else {
url += '?jsonp=' + callbackName;
}
// create the callback
window[callbackName] = function(result) {
$('jsonpScriptElement' + callbackID).remove();
callback(result);
window.splice(callbackName);
}
// Create the actual element (do this as the last thing because of caching)
// Assuming prototype.js usage
$$('body')[0].insert(new Element('script', {'href': url, 'id': 'jsonpScriptElement' + callbackID}));
}
Upvotes: 1
Views: 1418
Reputation: 57728
The only problem I see with it this is this part:
window[callbackName] = function(result) {
$('jsonpScriptElement' + callbackID).remove();
callback(result);
window.splice(callbackName);
}
You are making a new function for every call you make. Try to avoid this by making a generic function that is still safe to use asynchronously. Shouldn't be too hard to come up with something. You could for instance pass the sequence number along to the JSONp call and back to the callback so you can keep the different requests apart.
And yes, JSONp is really this easy :P
Additionally you can change your JSONp function to this:
var jsonp = (function() {
var callbackID = 0;
return function (url, callback) {
//.. function body ..
}
}());
So you don't have to declare callbackID
in the global scope
Upvotes: 3