X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/7a654f8d43fdb43d78b63d90528bed6e86b608cc..refs/heads/master:/docs/source/Connection.html diff --git a/docs/source/Connection.html b/docs/source/Connection.html index 54999ceb..6f9befb2 100644 --- a/docs/source/Connection.html +++ b/docs/source/Connection.html @@ -1,13 +1,29 @@ -
+ +/** - * @class Ext.data.Connection - * The Connection class encapsulates a connection to the page's originating domain, allowing requests to be made either + + + + +\ No newline at end of file +The source code + + + + + + +/** + * The Connection class encapsulates a connection to the page's originating domain, allowing requests to be made either * to a configured URL, or to a URL specified at request time. * * Requests made by this class are asynchronous, and will return immediately. No data from the server will be available * to the statement immediately following the {@link #request} call. To process returned data, use a success callback * in the request options object, or an {@link #requestcomplete event listener}. * - * <p><u>File Uploads</u></p> + * # File Uploads * * File uploads are not performed using normal "Ajax" techniques, that is they are not performed using XMLHttpRequests. * Instead the form is submitted in the standard manner with the DOM <form> element temporarily modified to have its @@ -18,8 +34,8 @@ * send the return object, then the Content-Type header must be set to "text/html" in order to tell the browser to * insert the text unchanged into the document body. * - * Characters which are significant to an HTML parser must be sent as HTML entities, so encode "<" as "&lt;", "&" as - * "&amp;" etc. + * Characters which are significant to an HTML parser must be sent as HTML entities, so encode `<` as `<`, `&` as + * `&` etc. * * The response text is retrieved from the document, and a fake XMLHttpRequest object is created containing a * responseText property in order to conform to the requirements of event handlers and callbacks. @@ -45,26 +61,40 @@ Ext.define('Ext.data.Connection', { username: '', password: '', - /** - * @cfg {Boolean} disableCaching (Optional) True to add a unique cache-buster param to GET requests. (defaults to true) - * @type Boolean + /** + * @cfg {Boolean} disableCaching + * True to add a unique cache-buster param to GET requests. */ disableCaching: true, - /** - * @cfg {String} disableCachingParam (Optional) Change the parameter which is sent went disabling caching - * through a cache buster. Defaults to '_dc' - * @type String + /** + * @cfg {Boolean} withCredentials + * True to set `withCredentials = true` on the XHR object + */ + withCredentials: false, + + /** + * @cfg {Boolean} cors + * True to enable CORS support on the XHR object. Currently the only effect of this option + * is to use the XDomainRequest object instead of XMLHttpRequest if the browser is IE8 or above. + */ + cors: false, + + /** + * @cfg {String} disableCachingParam + * Change the parameter which is sent went disabling caching through a cache buster. */ disableCachingParam: '_dc', - /** - * @cfg {Number} timeout (Optional) The timeout in milliseconds to be used for requests. (defaults to 30000) + /** + * @cfg {Number} timeout + * The timeout in milliseconds to be used for requests. */ timeout : 30000, - /** - * @param {Object} extraParams (Optional) Any parameters to be appended to the request. + /** + * @cfg {Object} extraParams + * Any parameters to be appended to the request. */ useDefaultHeader : true, @@ -77,32 +107,30 @@ Ext.define('Ext.data.Connection', { Ext.apply(this, config); this.addEvents( - /** + /** * @event beforerequest * Fires before a network request is made to retrieve a data object. - * @param {Connection} conn This Connection object. + * @param {Ext.data.Connection} conn This Connection object. * @param {Object} options The options config object passed to the {@link #request} method. */ 'beforerequest', - /** + /** * @event requestcomplete * Fires if the request was successfully completed. - * @param {Connection} conn This Connection object. + * @param {Ext.data.Connection} conn This Connection object. * @param {Object} response The XHR object containing the response data. - * See <a href="http://www.w3.org/TR/XMLHttpRequest/">The XMLHttpRequest Object</a> - * for details. + * See [The XMLHttpRequest Object](http://www.w3.org/TR/XMLHttpRequest/) for details. * @param {Object} options The options config object passed to the {@link #request} method. */ 'requestcomplete', - /** + /** * @event requestexception * Fires if an error HTTP status was returned from the server. - * See <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">HTTP Status Code Definitions</a> + * See [HTTP Status Code Definitions](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) * for details of HTTP status codes. - * @param {Connection} conn This Connection object. + * @param {Ext.data.Connection} conn This Connection object. * @param {Object} response The XHR object containing the response data. - * See <a href="http://www.w3.org/TR/XMLHttpRequest/">The XMLHttpRequest Object</a> - * for details. + * See [The XMLHttpRequest Object](http://www.w3.org/TR/XMLHttpRequest/) for details. * @param {Object} options The options config object passed to the {@link #request} method. */ 'requestexception' @@ -111,102 +139,113 @@ Ext.define('Ext.data.Connection', { this.mixins.observable.constructor.call(this); }, - /** - * <p>Sends an HTTP request to a remote server.</p> - * <p><b>Important:</b> Ajax server requests are asynchronous, and this call will + /** + * Sends an HTTP request to a remote server. + * + * **Important:** Ajax server requests are asynchronous, and this call will * return before the response has been received. Process any returned data - * in a callback function.</p> - * <pre><code> -Ext.Ajax.request({ -url: 'ajax_demo/sample.json', -success: function(response, opts) { - var obj = Ext.decode(response.responseText); - console.dir(obj); -}, -failure: function(response, opts) { - console.log('server-side failure with status code ' + response.status); -} -}); - * </code></pre> - * <p>To execute a callback function in the correct scope, use the <tt>scope</tt> option.</p> - * @param {Object} options An object which may contain the following properties:<ul> - * <li><b>url</b> : String/Function (Optional)<div class="sub-desc">The URL to - * which to send the request, or a function to call which returns a URL string. The scope of the - * function is specified by the <tt>scope</tt> option. Defaults to the configured - * <tt>{@link #url}</tt>.</div></li> - * <li><b>params</b> : Object/String/Function (Optional)<div class="sub-desc"> - * An object containing properties which are used as parameters to the - * request, a url encoded string or a function to call to get either. The scope of the function - * is specified by the <tt>scope</tt> option.</div></li> - * <li><b>method</b> : String (Optional)<div class="sub-desc">The HTTP method to use + * in a callback function. + * + * Ext.Ajax.request({ + * url: 'ajax_demo/sample.json', + * success: function(response, opts) { + * var obj = Ext.decode(response.responseText); + * console.dir(obj); + * }, + * failure: function(response, opts) { + * console.log('server-side failure with status code ' + response.status); + * } + * }); + * + * To execute a callback function in the correct scope, use the `scope` option. + * + * @param {Object} options An object which may contain the following properties: + * + * (The options object may also contain any other property which might be needed to perform + * postprocessing in a callback because it is passed to callback functions.) + * + * @param {String/Function} options.url The URL to which to send the request, or a function + * to call which returns a URL string. The scope of the function is specified by the `scope` option. + * Defaults to the configured `url`. + * + * @param {Object/String/Function} options.params An object containing properties which are + * used as parameters to the request, a url encoded string or a function to call to get either. The scope + * of the function is specified by the `scope` option. + * + * @param {String} options.method The HTTP method to use * for the request. Defaults to the configured method, or if no method was configured, * "GET" if no parameters are being sent, and "POST" if parameters are being sent. Note that - * the method name is case-sensitive and should be all caps.</div></li> - * <li><b>callback</b> : Function (Optional)<div class="sub-desc">The - * function to be called upon receipt of the HTTP response. The callback is - * called regardless of success or failure and is passed the following - * parameters:<ul> - * <li><b>options</b> : Object<div class="sub-desc">The parameter to the request call.</div></li> - * <li><b>success</b> : Boolean<div class="sub-desc">True if the request succeeded.</div></li> - * <li><b>response</b> : Object<div class="sub-desc">The XMLHttpRequest object containing the response data. - * See <a href="http://www.w3.org/TR/XMLHttpRequest/">http://www.w3.org/TR/XMLHttpRequest/</a> for details about - * accessing elements of the response.</div></li> - * </ul></div></li> - * <li><a id="request-option-success"></a><b>success</b> : Function (Optional)<div class="sub-desc">The function - * to be called upon success of the request. The callback is passed the following - * parameters:<ul> - * <li><b>response</b> : Object<div class="sub-desc">The XMLHttpRequest object containing the response data.</div></li> - * <li><b>options</b> : Object<div class="sub-desc">The parameter to the request call.</div></li> - * </ul></div></li> - * <li><b>failure</b> : Function (Optional)<div class="sub-desc">The function - * to be called upon failure of the request. The callback is passed the - * following parameters:<ul> - * <li><b>response</b> : Object<div class="sub-desc">The XMLHttpRequest object containing the response data.</div></li> - * <li><b>options</b> : Object<div class="sub-desc">The parameter to the request call.</div></li> - * </ul></div></li> - * <li><b>scope</b> : Object (Optional)<div class="sub-desc">The scope in - * which to execute the callbacks: The "this" object for the callback function. If the <tt>url</tt>, or <tt>params</tt> options were - * specified as functions from which to draw values, then this also serves as the scope for those function calls. - * Defaults to the browser window.</div></li> - * <li><b>timeout</b> : Number (Optional)<div class="sub-desc">The timeout in milliseconds to be used for this request. Defaults to 30 seconds.</div></li> - * <li><b>form</b> : Element/HTMLElement/String (Optional)<div class="sub-desc">The <tt><form></tt> - * Element or the id of the <tt><form></tt> to pull parameters from.</div></li> - * <li><a id="request-option-isUpload"></a><b>isUpload</b> : Boolean (Optional)<div class="sub-desc"><b>Only meaningful when used - * with the <tt>form</tt> option</b>. - * <p>True if the form object is a file upload (will be set automatically if the form was - * configured with <b><tt>enctype</tt></b> "multipart/form-data").</p> - * <p>File uploads are not performed using normal "Ajax" techniques, that is they are <b>not</b> + * the method name is case-sensitive and should be all caps. + * + * @param {Function} options.callback The function to be called upon receipt of the HTTP response. + * The callback is called regardless of success or failure and is passed the following parameters: + * @param {Object} options.callback.options The parameter to the request call. + * @param {Boolean} options.callback.success True if the request succeeded. + * @param {Object} options.callback.response The XMLHttpRequest object containing the response data. + * See [www.w3.org/TR/XMLHttpRequest/](http://www.w3.org/TR/XMLHttpRequest/) for details about + * accessing elements of the response. + * + * @param {Function} options.success The function to be called upon success of the request. + * The callback is passed the following parameters: + * @param {Object} options.success.response The XMLHttpRequest object containing the response data. + * @param {Object} options.success.options The parameter to the request call. + * + * @param {Function} options.failure The function to be called upon success of the request. + * The callback is passed the following parameters: + * @param {Object} options.failure.response The XMLHttpRequest object containing the response data. + * @param {Object} options.failure.options The parameter to the request call. + * + * @param {Object} options.scope The scope in which to execute the callbacks: The "this" object for + * the callback function. If the `url`, or `params` options were specified as functions from which to + * draw values, then this also serves as the scope for those function calls. Defaults to the browser + * window. + * + * @param {Number} options.timeout The timeout in milliseconds to be used for this request. + * Defaults to 30 seconds. + * + * @param {Ext.Element/HTMLElement/String} options.form The `<form>` Element or the id of the `<form>` + * to pull parameters from. + * + * @param {Boolean} options.isUpload **Only meaningful when used with the `form` option.** + * + * True if the form object is a file upload (will be set automatically if the form was configured + * with **`enctype`** `"multipart/form-data"`). + * + * File uploads are not performed using normal "Ajax" techniques, that is they are **not** * performed using XMLHttpRequests. Instead the form is submitted in the standard manner with the - * DOM <tt><form></tt> element temporarily modified to have its - * <a href="http://www.w3.org/TR/REC-html40/present/frames.html#adef-target">target</a> set to refer - * to a dynamically generated, hidden <tt><iframe></tt> which is inserted into the document - * but removed after the return data has been gathered.</p> - * <p>The server response is parsed by the browser to create the document for the IFRAME. If the - * server is using JSON to send the return object, then the - * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17">Content-Type</a> header - * must be set to "text/html" in order to tell the browser to insert the text unchanged into the document body.</p> - * <p>The response text is retrieved from the document, and a fake XMLHttpRequest object - * is created containing a <tt>responseText</tt> property in order to conform to the - * requirements of event handlers and callbacks.</p> - * <p>Be aware that file upload packets are sent with the content type <a href="http://www.faqs.org/rfcs/rfc2388.html">multipart/form</a> - * and some server technologies (notably JEE) may require some custom processing in order to - * retrieve parameter names and parameter values from the packet content.</p> - * </div></li> - * <li><b>headers</b> : Object (Optional)<div class="sub-desc">Request - * headers to set for the request.</div></li> - * <li><b>xmlData</b> : Object (Optional)<div class="sub-desc">XML document - * to use for the post. Note: This will be used instead of params for the post - * data. Any params will be appended to the URL.</div></li> - * <li><b>jsonData</b> : Object/String (Optional)<div class="sub-desc">JSON - * data to use as the post. Note: This will be used instead of params for the post - * data. Any params will be appended to the URL.</div></li> - * <li><b>disableCaching</b> : Boolean (Optional)<div class="sub-desc">True - * to add a unique cache-buster param to GET requests.</div></li> - * </ul></p> - * <p>The options object may also contain any other property which might be needed to perform - * postprocessing in a callback because it is passed to callback functions.</p> - * @return {Object} request The request object. This may be used - * to cancel the request. + * DOM `<form>` element temporarily modified to have its [target][] set to refer to a dynamically + * generated, hidden `<iframe>` which is inserted into the document but removed after the return data + * has been gathered. + * + * The server response is parsed by the browser to create the document for the IFRAME. If the + * server is using JSON to send the return object, then the [Content-Type][] header must be set to + * "text/html" in order to tell the browser to insert the text unchanged into the document body. + * + * The response text is retrieved from the document, and a fake XMLHttpRequest object is created + * containing a `responseText` property in order to conform to the requirements of event handlers + * and callbacks. + * + * Be aware that file upload packets are sent with the content type [multipart/form][] and some server + * technologies (notably JEE) may require some custom processing in order to retrieve parameter names + * and parameter values from the packet content. + * + * [target]: http://www.w3.org/TR/REC-html40/present/frames.html#adef-target + * [Content-Type]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17 + * [multipart/form]: http://www.faqs.org/rfcs/rfc2388.html + * + * @param {Object} options.headers Request headers to set for the request. + * + * @param {Object} options.xmlData XML document to use for the post. Note: This will be used instead + * of params for the post data. Any params will be appended to the URL. + * + * @param {Object/String} options.jsonData JSON data to use as the post. Note: This will be used + * instead of params for the post data. Any params will be appended to the URL. + * + * @param {Boolean} options.disableCaching True to add a unique cache-buster param to GET requests. + * + * @param {Boolean} options.withCredentials True to add the withCredentials property to the XHR object + * + * @return {Object} The request object. This may be used to cancel the request. */ request : function(options) { options = options || {}; @@ -235,7 +274,12 @@ failure: function(response, opts) { } // create a connection object - xhr = this.getXhrInstance(); + + if ((options.cors === true || me.cors === true) && Ext.isIE && Ext.ieVersion >= 8) { + xhr = new XDomainRequest(); + } else { + xhr = this.getXhrInstance(); + } async = options.async !== false ? (options.async || me.async) : false; @@ -246,6 +290,10 @@ failure: function(response, opts) { xhr.open(requestOptions.method, requestOptions.url, async); } + if (options.withCredentials === true || me.withCredentials === true) { + xhr.withCredentials = true; + } + headers = me.setupHeaders(xhr, options, requestOptions.data, requestOptions.params); // create the transaction object @@ -261,12 +309,18 @@ failure: function(response, opts) { }, options.timeout || me.timeout) }; me.requests[request.id] = request; - + me.latestId = request.id; // bind our statechange listener if (async) { xhr.onreadystatechange = Ext.Function.bind(me.onStateChange, me, [request]); } + if ((options.cors === true || me.cors === true) && Ext.isIE && Ext.ieVersion >= 8) { + xhr.onload = function() { + me.onComplete(request); + } + } + // start the request! xhr.send(requestOptions.data); if (!async) { @@ -279,14 +333,14 @@ failure: function(response, opts) { } }, - /** - * Upload a form using a hidden iframe. - * @param {Mixed} form The form to upload + /** + * Uploads a form using a hidden iframe. + * @param {String/HTMLElement/Ext.Element} form The form to upload * @param {String} url The url to post to * @param {String} params Any extra parameters to pass * @param {Object} options The initial options */ - upload: function(form, url, params, options){ + upload: function(form, url, params, options) { form = Ext.getDom(form); options = options || {}; @@ -352,7 +406,13 @@ failure: function(response, opts) { }); }, - onUploadComplete: function(frame, options){ + /** + * @private + * Callback handler for the upload function. After we've submitted the form via the iframe this creates a bogus + * response object to simulate an XHR and populates its responseText from the now-loaded iframe's document body + * (or a textarea inside the body). We then clean up by removing the iframe + */ + onUploadComplete: function(frame, options) { var me = this, // bogus response object response = { @@ -361,7 +421,7 @@ failure: function(response, opts) { }, doc, firstChild; try { - doc = frame.contentWindow.document || frame.contentDocument || window.frames[id].document; + doc = frame.contentWindow.document || frame.contentDocument || window.frames[frame.id].document; if (doc) { if (doc.body) { if (/textarea/i.test((firstChild = doc.body.firstChild || {}).tagName)) { // json response wrapped in textarea @@ -386,8 +446,8 @@ failure: function(response, opts) { }, 100); }, - /** - * Detect whether the form is intended to be used for an upload. + /** + * Detects whether the form is intended to be used for an upload. * @private */ isFormUpload: function(options){ @@ -398,8 +458,8 @@ failure: function(response, opts) { return false; }, - /** - * Get the form object from options. + /** + * Gets the form object from options. * @private * @param {Object} options The request options * @return {HTMLElement} The form, null if not passed @@ -408,8 +468,8 @@ failure: function(response, opts) { return Ext.getDom(options.form) || null; }, - /** - * Set various options such as the url, params for the request + /** + * Sets various options such as the url, params for the request * @param {Object} options The initial options * @param {Object} scope The scope to execute in * @return {Object} The params for the request @@ -497,8 +557,9 @@ failure: function(response, opts) { }; }, - /** + /** * Template method for overriding url + * @template * @private * @param {Object} options * @param {String} url @@ -513,8 +574,9 @@ failure: function(response, opts) { }, - /** + /** * Template method for overriding params + * @template * @private * @param {Object} options * @param {String} params @@ -524,14 +586,15 @@ failure: function(response, opts) { var form = this.getForm(options), serializedForm; if (form && !this.isFormUpload(options)) { - serializedForm = Ext.core.Element.serializeForm(form); + serializedForm = Ext.Element.serializeForm(form); params = params ? (params + '&' + serializedForm) : serializedForm; } return params; }, - /** + /** * Template method for overriding method + * @template * @private * @param {Object} options * @param {String} method @@ -544,7 +607,7 @@ failure: function(response, opts) { return method; }, - /** + /** * Setup all the headers for the request * @private * @param {Object} xhr The xhr object @@ -594,7 +657,7 @@ failure: function(response, opts) { return headers; }, - /** + /** * Creates the appropriate XHR transport for the browser. * @private */ @@ -621,12 +684,15 @@ failure: function(response, opts) { return xhr; })(), - /** - * Determine whether this object has a request outstanding. - * @param {Object} request (Optional) defaults to the last transaction + /** + * Determines whether this object has a request outstanding. + * @param {Object} [request] Defaults to the last transaction * @return {Boolean} True if there is an outstanding request. */ isLoading : function(request) { + if (!request) { + request = this.getLatest(); + } if (!(request && request.xhr)) { return false; } @@ -635,18 +701,20 @@ failure: function(response, opts) { return !(state === 0 || state == 4); }, - /** - * Aborts any outstanding request. - * @param {Object} request (Optional) defaults to the last request + /** + * Aborts an active request. + * @param {Object} [request] Defaults to the last request */ abort : function(request) { - var me = this, - requests = me.requests, - id; + var me = this; + + if (!request) { + request = me.getLatest(); + } if (request && me.isLoading(request)) { - /** - * Clear out the onreadystatechange here, this allows us + /* + * Clear out the onreadystatechange here, this allows us * greater control, the browser may/may not fire the function * depending on a series of conditions. */ @@ -658,16 +726,39 @@ failure: function(response, opts) { } me.onComplete(request); me.cleanup(request); - } else if (!request) { - for(id in requests) { - if (requests.hasOwnProperty(id)) { - me.abort(requests[id]); - } + } + }, + + /** + * Aborts all active requests + */ + abortAll: function(){ + var requests = this.requests, + id; + + for (id in requests) { + if (requests.hasOwnProperty(id)) { + this.abort(requests[id]); } } }, - /** + /** + * Gets the most recent request + * @private + * @return {Object} The request. Null if there is no recent request + */ + getLatest: function(){ + var id = this.latestId, + request; + + if (id) { + request = this.requests[id]; + } + return request || null; + }, + + /** * Fires when the state of the xhr changes * @private * @param {Object} request The request @@ -680,8 +771,8 @@ failure: function(response, opts) { } }, - /** - * Clear the timeout on the request + /** + * Clears the timeout on the request * @private * @param {Object} The request */ @@ -690,8 +781,8 @@ failure: function(response, opts) { delete request.timeout; }, - /** - * Clean up any left over information from the request + /** + * Cleans up any left over information from the request * @private * @param {Object} The request */ @@ -700,7 +791,7 @@ failure: function(response, opts) { delete request.xhr; }, - /** + /** * To be called when the request has come back from the server * @private * @param {Object} request @@ -709,10 +800,21 @@ failure: function(response, opts) { onComplete : function(request) { var me = this, options = request.options, - result = me.parseStatus(request.xhr.status), - success = result.success, + result, + success, response; + try { + result = me.parseStatus(request.xhr.status); + } catch (e) { + // in some browsers we can't access the status if the readyState is not 4, so the request has failed + result = { + success : false, + isException : false + }; + } + success = result.success; + if (success) { response = me.createResponse(request); me.fireEvent('requestcomplete', me, response, options); @@ -731,8 +833,8 @@ failure: function(response, opts) { return response; }, - /** - * Check if the response status was successful + /** + * Checks if the response status was successful * @param {Number} status The status code * @return {Object} An object containing success/status state */ @@ -761,15 +863,15 @@ failure: function(response, opts) { }; }, - /** - * Create the response object + /** + * Creates the response object * @private * @param {Object} request */ createResponse : function(request) { var xhr = request.xhr, headers = {}, - lines = xhr.getAllResponseHeaders().replace(/\r\n/g, '\n').split('\n'), + lines = xhr.getAllResponseHeaders ? xhr.getAllResponseHeaders().replace(/\r\n/g, '\n').split('\n') : [], count = lines.length, line, index, key, value, response; @@ -805,8 +907,8 @@ failure: function(response, opts) { return response; }, - /** - * Create the exception object + /** + * Creates the exception object * @private * @param {Object} request */ @@ -821,4 +923,6 @@ failure: function(response, opts) { }; } }); -