| // Copyright 2006 The Closure Library Authors. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS-IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| /** |
| * @fileoverview Low level handling of XMLHttpRequest. |
| * @author arv@google.com (Erik Arvidsson) |
| * @author dbk@google.com (David Barrett-Kahn) |
| */ |
| |
| goog.provide('goog.net.DefaultXmlHttpFactory'); |
| goog.provide('goog.net.XmlHttp'); |
| goog.provide('goog.net.XmlHttp.OptionType'); |
| goog.provide('goog.net.XmlHttp.ReadyState'); |
| goog.provide('goog.net.XmlHttpDefines'); |
| |
| goog.require('goog.asserts'); |
| goog.require('goog.net.WrapperXmlHttpFactory'); |
| goog.require('goog.net.XmlHttpFactory'); |
| |
| |
| /** |
| * Static class for creating XMLHttpRequest objects. |
| * @return {!goog.net.XhrLike.OrNative} A new XMLHttpRequest object. |
| */ |
| goog.net.XmlHttp = function() { |
| return goog.net.XmlHttp.factory_.createInstance(); |
| }; |
| |
| |
| /** |
| * @define {boolean} Whether to assume XMLHttpRequest exists. Setting this to |
| * true bypasses the ActiveX probing code. |
| * NOTE(ruilopes): Due to the way JSCompiler works, this define *will not* strip |
| * out the ActiveX probing code from binaries. To achieve this, use |
| * {@code goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR} instead. |
| * TODO(ruilopes): Collapse both defines. |
| */ |
| goog.define('goog.net.XmlHttp.ASSUME_NATIVE_XHR', false); |
| |
| |
| /** @const */ |
| goog.net.XmlHttpDefines = {}; |
| |
| |
| /** |
| * @define {boolean} Whether to assume XMLHttpRequest exists. Setting this to |
| * true eliminates the ActiveX probing code. |
| */ |
| goog.define('goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR', false); |
| |
| |
| /** |
| * Gets the options to use with the XMLHttpRequest objects obtained using |
| * the static methods. |
| * @return {Object} The options. |
| */ |
| goog.net.XmlHttp.getOptions = function() { |
| return goog.net.XmlHttp.factory_.getOptions(); |
| }; |
| |
| |
| /** |
| * Type of options that an XmlHttp object can have. |
| * @enum {number} |
| */ |
| goog.net.XmlHttp.OptionType = { |
| /** |
| * Whether a goog.nullFunction should be used to clear the onreadystatechange |
| * handler instead of null. |
| */ |
| USE_NULL_FUNCTION: 0, |
| |
| /** |
| * NOTE(user): In IE if send() errors on a *local* request the readystate |
| * is still changed to COMPLETE. We need to ignore it and allow the |
| * try/catch around send() to pick up the error. |
| */ |
| LOCAL_REQUEST_ERROR: 1 |
| }; |
| |
| |
| /** |
| * Status constants for XMLHTTP, matches: |
| * https://msdn.microsoft.com/en-us/library/ms534361(v=vs.85).aspx |
| * @enum {number} |
| */ |
| goog.net.XmlHttp.ReadyState = { |
| /** |
| * Constant for when xmlhttprequest.readyState is uninitialized |
| */ |
| UNINITIALIZED: 0, |
| |
| /** |
| * Constant for when xmlhttprequest.readyState is loading. |
| */ |
| LOADING: 1, |
| |
| /** |
| * Constant for when xmlhttprequest.readyState is loaded. |
| */ |
| LOADED: 2, |
| |
| /** |
| * Constant for when xmlhttprequest.readyState is in an interactive state. |
| */ |
| INTERACTIVE: 3, |
| |
| /** |
| * Constant for when xmlhttprequest.readyState is completed |
| */ |
| COMPLETE: 4 |
| }; |
| |
| |
| /** |
| * The global factory instance for creating XMLHttpRequest objects. |
| * @type {goog.net.XmlHttpFactory} |
| * @private |
| */ |
| goog.net.XmlHttp.factory_; |
| |
| |
| /** |
| * Sets the factories for creating XMLHttpRequest objects and their options. |
| * @param {Function} factory The factory for XMLHttpRequest objects. |
| * @param {Function} optionsFactory The factory for options. |
| * @deprecated Use setGlobalFactory instead. |
| */ |
| goog.net.XmlHttp.setFactory = function(factory, optionsFactory) { |
| goog.net.XmlHttp.setGlobalFactory( |
| new goog.net.WrapperXmlHttpFactory( |
| goog.asserts.assert(factory), goog.asserts.assert(optionsFactory))); |
| }; |
| |
| |
| /** |
| * Sets the global factory object. |
| * @param {!goog.net.XmlHttpFactory} factory New global factory object. |
| */ |
| goog.net.XmlHttp.setGlobalFactory = function(factory) { |
| goog.net.XmlHttp.factory_ = factory; |
| }; |
| |
| |
| |
| /** |
| * Default factory to use when creating xhr objects. You probably shouldn't be |
| * instantiating this directly, but rather using it via goog.net.XmlHttp. |
| * @extends {goog.net.XmlHttpFactory} |
| * @constructor |
| */ |
| goog.net.DefaultXmlHttpFactory = function() { |
| goog.net.XmlHttpFactory.call(this); |
| }; |
| goog.inherits(goog.net.DefaultXmlHttpFactory, goog.net.XmlHttpFactory); |
| |
| |
| /** @override */ |
| goog.net.DefaultXmlHttpFactory.prototype.createInstance = function() { |
| var progId = this.getProgId_(); |
| if (progId) { |
| return new ActiveXObject(progId); |
| } else { |
| return new XMLHttpRequest(); |
| } |
| }; |
| |
| |
| /** @override */ |
| goog.net.DefaultXmlHttpFactory.prototype.internalGetOptions = function() { |
| var progId = this.getProgId_(); |
| var options = {}; |
| if (progId) { |
| options[goog.net.XmlHttp.OptionType.USE_NULL_FUNCTION] = true; |
| options[goog.net.XmlHttp.OptionType.LOCAL_REQUEST_ERROR] = true; |
| } |
| return options; |
| }; |
| |
| |
| /** |
| * The ActiveX PROG ID string to use to create xhr's in IE. Lazily initialized. |
| * @type {string|undefined} |
| * @private |
| */ |
| goog.net.DefaultXmlHttpFactory.prototype.ieProgId_; |
| |
| |
| /** |
| * Initialize the private state used by other functions. |
| * @return {string} The ActiveX PROG ID string to use to create xhr's in IE. |
| * @private |
| */ |
| goog.net.DefaultXmlHttpFactory.prototype.getProgId_ = function() { |
| if (goog.net.XmlHttp.ASSUME_NATIVE_XHR || |
| goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR) { |
| return ''; |
| } |
| |
| // The following blog post describes what PROG IDs to use to create the |
| // XMLHTTP object in Internet Explorer: |
| // http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx |
| // However we do not (yet) fully trust that this will be OK for old versions |
| // of IE on Win9x so we therefore keep the last 2. |
| if (!this.ieProgId_ && typeof XMLHttpRequest == 'undefined' && |
| typeof ActiveXObject != 'undefined') { |
| // Candidate Active X types. |
| var ACTIVE_X_IDENTS = [ |
| 'MSXML2.XMLHTTP.6.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', |
| 'Microsoft.XMLHTTP' |
| ]; |
| for (var i = 0; i < ACTIVE_X_IDENTS.length; i++) { |
| var candidate = ACTIVE_X_IDENTS[i]; |
| |
| try { |
| new ActiveXObject(candidate); |
| // NOTE(user): cannot assign progid and return candidate in one line |
| // because JSCompiler complaings: BUG 658126 |
| this.ieProgId_ = candidate; |
| return candidate; |
| } catch (e) { |
| // do nothing; try next choice |
| } |
| } |
| |
| // couldn't find any matches |
| throw Error( |
| 'Could not create ActiveXObject. ActiveX might be disabled,' + |
| ' or MSXML might not be installed'); |
| } |
| |
| return /** @type {string} */ (this.ieProgId_); |
| }; |
| |
| |
| // Set the global factory to an instance of the default factory. |
| goog.net.XmlHttp.setGlobalFactory(new goog.net.DefaultXmlHttpFactory()); |