Skip to content

Instantly share code, notes, and snippets.

@putermancer
Created November 26, 2011 06:18
Show Gist options
  • Save putermancer/1395160 to your computer and use it in GitHub Desktop.
Save putermancer/1395160 to your computer and use it in GitHub Desktop.
jsonp (maybe not entirely cross-browser friendly)
/**
* Function: getRandomId
* Generates a unique-ish hex string between 1 and 32 characters long.
*/
rrandomidreplace : /x/g,
getRandomId : function(length) {
length = length && length > 0 && length <= 32 ? length : 32;
function getHexChar() {
var r = Math.random()*16|0;
return r.toString(16);
}
return ('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'.substring(0,length)).replace(this.rrandomidreplace, getHexChar);
},
/**
* Function: jsonp
* Creates a jsonp request with the specified url and callback. The url
* should contain a query parameter as x=? for the param the receiving
* server expects to contain the callback function name. '=?' will be
* replaced with a unique callback function that invokes the caller's cb.
*
* Parameters:
* url:String - url to request, including [x]=? for the callback parameter
* cb:Function - callback function
* timeout:Number - how many MS to wait before invoking cb with a status
* of "error" and null data (default: 1500)
*/
jsonp : function(url, cb, timeout) {
if (!url || typeof(url) == "undefined" || typeof(cb) != "function") {
return false;
}
timeout = Math.abs(timeout) || 1500;
var self = this;
// generate unique callback function
var uniqueCb = "cb" + this.getRandomId();
var t = 0;
window[uniqueCb] = function(data){
clearTimeout(t);
cb(data, "success");
window[uniqueCb] = null;
self.removeJsonpScriptTag(uniqueCb);
};
this.createJsonpScriptTag(url, uniqueCb);
t = setTimeout(function() {
// in case it eventually comes back, this prevents it invoking a function that doesn't exist
window[uniqueCb] = function(){ window[uniqueCb] = null; };
cb(null, "error");
self.removeJsonpScriptTag(uniqueCb);
}, timeout);
},
/**
* Function: createJsonpScriptTag
* Creates a SCRIPT tag on the page for a jsonp request by appending the
* provided cb_name to the provided URL.
*
* Parameters:
* url:String - the url to load. Ideally, includes "[callback]=?" where
* callback is the param the server API expects for the JSONP
* callback. If not provided, "callback" is used.
* cb_name:String - name of the global (window) function to use as the
* JSONP callback
*/
rcallback : /\=\?/g, // Used to replace jsonp callbacks with unique cb function name
createJsonpScriptTag : function(url, cb_name) {
if (!url || !cb_name || typeof(url) != "string" || typeof(cb_name) != "string") {
return;
}
if (url.indexOf("=?") != -1) {
url = url.replace(this.rcallback, "=" + cb_name);
}
else {
url += (url.indexOf("?") === -1 ? "?callback=" : "&callback=") + cb_name;
}
var script = document.createElement("script");
script.id = "jsonp-" + cb_name;
script.type = "text/javascript";
script.charset = "utf-8";
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
},
/**
* Function: removeJsonpScriptTag
* Removes the SCRIPT tag for a given cb_name from the document.
*
* Parameters:
* cb_name:String - name of the global (window) function that was used as
* the JSONP callback
*/
removeJsonpScriptTag : function(cb_name) {
var script = document.getElementById("jsonp-" + cb_name);
if (!script) {
return;
}
script.parentNode.removeChild(script);
for (var prop in script) {
if (script.hasOwnProperty(prop)) {
delete script[prop];
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment