2 * @class Ext.data.JsonP
4 * This class is used to create JSONP requests. JSONP is a mechanism that allows for making
5 * requests for data cross domain. More information is available here:
6 * http://en.wikipedia.org/wiki/JSONP
8 Ext.define('Ext.data.JsonP', {
10 /* Begin Definitions */
24 * A default timeout for any JsonP requests. If the request has not completed in this time the
25 * failure callback will be fired. The timeout is in ms. Defaults to <tt>30000</tt>.
30 * @property disableCaching
32 * True to add a unique cache-buster param to requests. Defaults to <tt>true</tt>.
37 * @property disableCachingParam
39 * Change the parameter which is sent went disabling caching through a cache buster. Defaults to <tt>'_dc'</tt>.
41 disableCachingParam: '_dc',
44 * @property callbackKey
46 * Specifies the GET parameter that will be sent to the server containing the function name to be executed when
47 * the request completes. Defaults to <tt>callback</tt>. Thus, a common request will be in the form of
48 * url?callback=Ext.data.JsonP.callback1
50 callbackKey: 'callback',
53 * Makes a JSONP request.
54 * @param {Object} options An object which may contain the following properties. Note that options will
55 * take priority over any defaults that are specified in the class.
57 * <li><b>url</b> : String <div class="sub-desc">The URL to request.</div></li>
58 * <li><b>params</b> : Object (Optional)<div class="sub-desc">An object containing a series of
59 * key value pairs that will be sent along with the request.</div></li>
60 * <li><b>timeout</b> : Number (Optional) <div class="sub-desc">See {@link #timeout}</div></li>
61 * <li><b>callbackKey</b> : String (Optional) <div class="sub-desc">See {@link #callbackKey}</div></li>
62 * <li><b>callbackName</b> : String (Optional) <div class="sub-desc">The function name to use for this request.
63 * By default this name will be auto-generated: Ext.data.JsonP.callback1, Ext.data.JsonP.callback2, etc.
64 * Setting this option to "my_name" will force the function name to be Ext.data.JsonP.my_name.
65 * Use this if you want deterministic behavior, but be careful - the callbackName should be different
66 * in each JsonP request that you make.</div></li>
67 * <li><b>disableCaching</b> : Boolean (Optional) <div class="sub-desc">See {@link #disableCaching}</div></li>
68 * <li><b>disableCachingParam</b> : String (Optional) <div class="sub-desc">See {@link #disableCachingParam}</div></li>
69 * <li><b>success</b> : Function (Optional) <div class="sub-desc">A function to execute if the request succeeds.</div></li>
70 * <li><b>failure</b> : Function (Optional) <div class="sub-desc">A function to execute if the request fails.</div></li>
71 * <li><b>callback</b> : Function (Optional) <div class="sub-desc">A function to execute when the request
72 * completes, whether it is a success or failure.</div></li>
73 * <li><b>scope</b> : Object (Optional)<div class="sub-desc">The scope in
74 * which to execute the callbacks: The "this" object for the callback function. Defaults to the browser window.</div></li>
76 * @return {Object} request An object containing the request details.
78 request: function(options){
79 options = Ext.apply({}, options);
83 Ext.Error.raise('A url must be specified for a JSONP request.');
88 disableCaching = Ext.isDefined(options.disableCaching) ? options.disableCaching : me.disableCaching,
89 cacheParam = options.disableCachingParam || me.disableCachingParam,
90 id = ++me.statics().requestCount,
91 callbackName = options.callbackName || 'callback' + id,
92 callbackKey = options.callbackKey || me.callbackKey,
93 timeout = Ext.isDefined(options.timeout) ? options.timeout : me.timeout,
94 params = Ext.apply({}, options.params),
99 params[callbackKey] = 'Ext.data.JsonP.' + callbackName;
100 if (disableCaching) {
101 params[cacheParam] = new Date().getTime();
104 script = me.createScript(url, params);
106 me.statics().requests[id] = request = {
111 scope: options.scope,
112 success: options.success,
113 failure: options.failure,
114 callback: options.callback,
115 callbackName: callbackName
119 request.timeout = setTimeout(Ext.bind(me.handleTimeout, me, [request]), timeout);
122 me.setupErrorHandling(request);
123 me[callbackName] = Ext.bind(me.handleResponse, me, [request], true);
124 Ext.getHead().appendChild(script);
129 * Abort a request. If the request parameter is not specified all open requests will
131 * @param {Object/String} request (Optional) The request to abort
133 abort: function(request){
134 var requests = this.statics().requests,
139 request = requests[request];
143 for (key in requests) {
144 if (requests.hasOwnProperty(key)) {
145 this.abort(requests[key]);
152 * Sets up error handling for the script
154 * @param {Object} request The request
156 setupErrorHandling: function(request){
157 request.script.onerror = Ext.bind(this.handleError, this, [request]);
161 * Handles any aborts when loading the script
163 * @param {Object} request The request
165 handleAbort: function(request){
166 request.errorType = 'abort';
167 this.handleResponse(null, request);
171 * Handles any script errors when loading the script
173 * @param {Object} request The request
175 handleError: function(request){
176 request.errorType = 'error';
177 this.handleResponse(null, request);
181 * Cleans up anu script handling errors
183 * @param {Object} request The request
185 cleanupErrorHandling: function(request){
186 request.script.onerror = null;
190 * Handle any script timeouts
192 * @param {Object} request The request
194 handleTimeout: function(request){
195 request.errorType = 'timeout';
196 this.handleResponse(null, request);
200 * Handle a successful response
202 * @param {Object} result The result from the request
203 * @param {Object} request The request
205 handleResponse: function(result, request){
209 if (request.timeout) {
210 clearTimeout(request.timeout);
212 delete this[request.callbackName];
213 delete this.statics()[request.id];
214 this.cleanupErrorHandling(request);
215 Ext.fly(request.script).remove();
217 if (request.errorType) {
219 Ext.callback(request.failure, request.scope, [request.errorType]);
221 Ext.callback(request.success, request.scope, [result]);
223 Ext.callback(request.callback, request.scope, [success, result, request.errorType]);
227 * Create the script tag
229 * @param {String} url The url of the request
230 * @param {Object} params Any extra params to be sent
232 createScript: function(url, params) {
233 var script = document.createElement('script');
234 script.setAttribute("src", Ext.urlAppend(url, Ext.Object.toQueryString(params)));
235 script.setAttribute("async", true);
236 script.setAttribute("type", "text/javascript");