Created
November 26, 2011 06:18
-
-
Save putermancer/1395160 to your computer and use it in GitHub Desktop.
jsonp (maybe not entirely cross-browser friendly)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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