-
-
Save palermomarco/3438695 to your computer and use it in GitHub Desktop.
JSONP for PrototypeJS
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
// See an updated version of this in it's own git repo: | |
// http://github.com/dandean/Ajax.JSONRequest | |
/* JSON-P implementation for Prototype.js somewhat by Dan Dean (http://www.dandean.com) | |
* | |
* *HEAVILY* based on Tobie Langel's version: http://gist.github.com/145466. | |
* Might as well just call this an iteration. | |
* | |
* This version introduces: | |
* - onCreate and onFailure callback options. | |
* - option to not invoke request upon instantiation. | |
* | |
* Tested in Firefox 3/3.5, Safari 4 | |
* | |
* Note: while I still think JSON-P is an inherantly flawed technique, | |
* there are some valid use cases which this can provide for. | |
* | |
* See examples below for usage. | |
*/ | |
Ajax.JSONRequest = Class.create(Ajax.Base, (function() { | |
var id = 0, head = document.getElementsByTagName('head')[0]; | |
return { | |
initialize: function($super, url, options) { | |
$super(options); | |
this.options.url = url; | |
this.options.callbackParamName = this.options.callbackParamName || 'callback'; | |
this.options.timeout = this.options.timeout || 10000; // Default timeout: 10 seconds | |
this.options.invokeImmediately = (!Object.isUndefined(this.options.invokeImmediately)) ? this.options.invokeImmediately : true ; | |
this.responseJSON = {}; | |
if (this.options.invokeImmediately) { | |
this.request(); | |
} | |
}, | |
/** | |
* Ajax.JSONRequest#_cleanup() -> "undefined" | |
* | |
* Cleans up after the request | |
**/ | |
_cleanup: function() { | |
if (this.timeout) { | |
clearTimeout(this.timeout); | |
this.timeout = null; | |
} | |
if (this.script && Object.isElement(this.script)) { | |
this.script.remove(); | |
this.script = null; | |
} | |
}, | |
/** | |
* Ajax.JSONRequest#request() -> "undefined" | |
* | |
* Invokes the JSON-P request lifecycle | |
**/ | |
request: function() { | |
// Define local vars | |
var key = this.options.callbackParamName, | |
name = '_prototypeJSONPCallback_' + (id++); | |
// Add callback as a parameter and build request URL | |
this.options.parameters[key] = name; | |
var url = this.options.url + ((this.options.url.include('?') ? '&' : '?') + Object.toQueryString(this.options.parameters)); | |
// Define callback function | |
window[name] = function(json) { | |
this._cleanup(); // Garbage collection | |
window[name] = undefined; | |
if (Object.isFunction(this.options.onComplete)) { | |
this.responseJSON = json; | |
this.options.onComplete.call(this, this); | |
} | |
}.bind(this); | |
this.script = new Element('script', { type: 'text/javascript', src: url }); | |
if (Object.isFunction(this.options.onCreate)) { | |
this.options.onCreate.call(this, this); | |
} | |
head.appendChild(this.script); | |
this.timeout = setTimeout(function() { | |
this._cleanup(); | |
window[name] = Prototype.emptyFunction; | |
if (Object.isFunction(this.options.onFailure)) { | |
this.options.onFailure.call(this, this); | |
} | |
}.bind(this), this.options.timeout); | |
} | |
}; | |
})()); | |
// | |
// EXAMPLES | |
// | |
document.observe("dom:loaded", function(e) { | |
// Should succeed | |
new Ajax.JSONRequest('http://api.flickr.com/services/feeds/photos_public.gne', { | |
onCreate: function(instance) { | |
console.log("create", this); | |
}, | |
onComplete: function(instance) { | |
console.log("complete", this); | |
}, | |
onFailure: function(instance) { | |
console.log("fail", this); | |
}, | |
callbackParamName: "jsoncallback", | |
parameters: { | |
tags: 'cat', | |
tagmode: 'any', | |
format: 'json' | |
} | |
}); | |
// Timeout is super short, should fail | |
new Ajax.JSONRequest('http://api.flickr.com/services/feeds/photos_public.gne', { | |
onCreate: function(instance) { | |
console.log("create", this); | |
}, | |
onComplete: function(instance) { | |
console.log("complete", this); | |
}, | |
onFailure: function(instance) { | |
console.log("fail", this); | |
}, | |
// Adding super short timeout | |
timeout: 100, | |
callbackParamName: "jsoncallback", | |
parameters: { | |
tags: 'cat', | |
tagmode: 'any', | |
format: 'json' | |
} | |
}); | |
// Invalid URL never calls onComplete. Times out in 10 seconds causing onFailure. | |
new Ajax.JSONRequest('http://api.flickr.com/services/feeds/asdfasdfasdfasdfasdfsdf', { | |
onCreate: function(instance) { | |
console.log("create", this); | |
}, | |
onComplete: function(instance) { | |
console.log("complete", this); | |
}, | |
onFailure: function(instance) { | |
console.log("fail", this); | |
}, | |
callbackParamName: "jsoncallback", | |
parameters: { | |
tags: 'cat', | |
tagmode: 'any', | |
format: 'json' | |
} | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment