# lib/goog/net/xmlhttp.js

    1// Copyright 2006 The Closure Library Authors. All Rights Reserved.2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7//      http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS-IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.1415/**16 * @fileoverview Low level handling of XMLHttpRequest.17 * @author arv@google.com (Erik Arvidsson)18 * @author dbk@google.com (David Barrett-Kahn)19 */2021goog.provide('goog.net.DefaultXmlHttpFactory');22goog.provide('goog.net.XmlHttp');23goog.provide('goog.net.XmlHttp.OptionType');24goog.provide('goog.net.XmlHttp.ReadyState');25goog.provide('goog.net.XmlHttpDefines');2627goog.require('goog.asserts');28goog.require('goog.net.WrapperXmlHttpFactory');29goog.require('goog.net.XmlHttpFactory');303132/**33 * Static class for creating XMLHttpRequest objects.34 * @return {!goog.net.XhrLike.OrNative} A new XMLHttpRequest object.35 */36goog.net.XmlHttp = function() {37  return goog.net.XmlHttp.factory_.createInstance();38};394041/**42 * @define {boolean} Whether to assume XMLHttpRequest exists. Setting this to43 *     true bypasses the ActiveX probing code.44 * NOTE(user): Due to the way JSCompiler works, this define *will not* strip45 * out the ActiveX probing code from binaries.  To achieve this, use46 * {@code goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR} instead.47 * TODO(user): Collapse both defines.48 */49goog.define('goog.net.XmlHttp.ASSUME_NATIVE_XHR', false);505152/** @const */53goog.net.XmlHttpDefines = {};545556/**57 * @define {boolean} Whether to assume XMLHttpRequest exists. Setting this to58 *     true eliminates the ActiveX probing code.59 */60goog.define('goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR', false);616263/**64 * Gets the options to use with the XMLHttpRequest objects obtained using65 * the static methods.66 * @return {Object} The options.67 */68goog.net.XmlHttp.getOptions = function() {69  return goog.net.XmlHttp.factory_.getOptions();70};717273/**74 * Type of options that an XmlHttp object can have.75 * @enum {number}76 */77goog.net.XmlHttp.OptionType = {78  /**79   * Whether a goog.nullFunction should be used to clear the onreadystatechange80   * handler instead of null.81   */82  USE_NULL_FUNCTION: 0,8384  /**85   * NOTE(user): In IE if send() errors on a *local* request the readystate86   * is still changed to COMPLETE.  We need to ignore it and allow the87   * try/catch around send() to pick up the error.88   */89  LOCAL_REQUEST_ERROR: 190};919293/**94 * Status constants for XMLHTTP, matches:95 * http://msdn.microsoft.com/library/default.asp?url=/library/96 *   en-us/xmlsdk/html/0e6a34e4-f90c-489d-acff-cb44242fafc6.asp97 * @enum {number}98 */99goog.net.XmlHttp.ReadyState = {100  /**101   * Constant for when xmlhttprequest.readyState is uninitialized102   */103  UNINITIALIZED: 0,104105  /**106   * Constant for when xmlhttprequest.readyState is loading.107   */108  LOADING: 1,109110  /**111   * Constant for when xmlhttprequest.readyState is loaded.112   */113  LOADED: 2,114115  /**116   * Constant for when xmlhttprequest.readyState is in an interactive state.117   */118  INTERACTIVE: 3,119120  /**121   * Constant for when xmlhttprequest.readyState is completed122   */123  COMPLETE: 4124};125126127/**128 * The global factory instance for creating XMLHttpRequest objects.129 * @type {goog.net.XmlHttpFactory}130 * @private131 */132goog.net.XmlHttp.factory_;133134135/**136 * Sets the factories for creating XMLHttpRequest objects and their options.137 * @param {Function} factory The factory for XMLHttpRequest objects.138 * @param {Function} optionsFactory The factory for options.139 * @deprecated Use setGlobalFactory instead.140 */141goog.net.XmlHttp.setFactory = function(factory, optionsFactory) {142  goog.net.XmlHttp.setGlobalFactory(new goog.net.WrapperXmlHttpFactory(143      goog.asserts.assert(factory),144      goog.asserts.assert(optionsFactory)));145};146147148/**149 * Sets the global factory object.150 * @param {!goog.net.XmlHttpFactory} factory New global factory object.151 */152goog.net.XmlHttp.setGlobalFactory = function(factory) {153  goog.net.XmlHttp.factory_ = factory;154};155156157158/**159 * Default factory to use when creating xhr objects.  You probably shouldn't be160 * instantiating this directly, but rather using it via goog.net.XmlHttp.161 * @extends {goog.net.XmlHttpFactory}162 * @constructor163 */164goog.net.DefaultXmlHttpFactory = function() {165  goog.net.XmlHttpFactory.call(this);166};167goog.inherits(goog.net.DefaultXmlHttpFactory, goog.net.XmlHttpFactory);168169170/** @override */171goog.net.DefaultXmlHttpFactory.prototype.createInstance = function() {172  var progId = this.getProgId_();173  if (progId) {174    return new ActiveXObject(progId);175  } else {176    return new XMLHttpRequest();177  }178};179180181/** @override */182goog.net.DefaultXmlHttpFactory.prototype.internalGetOptions = function() {183  var progId = this.getProgId_();184  var options = {};185  if (progId) {186    options[goog.net.XmlHttp.OptionType.USE_NULL_FUNCTION] = true;187    options[goog.net.XmlHttp.OptionType.LOCAL_REQUEST_ERROR] = true;188  }189  return options;190};191192193/**194 * The ActiveX PROG ID string to use to create xhr's in IE. Lazily initialized.195 * @type {string|undefined}196 * @private197 */198goog.net.DefaultXmlHttpFactory.prototype.ieProgId_;199200201/**202 * Initialize the private state used by other functions.203 * @return {string} The ActiveX PROG ID string to use to create xhr's in IE.204 * @private205 */206goog.net.DefaultXmlHttpFactory.prototype.getProgId_ = function() {207  if (goog.net.XmlHttp.ASSUME_NATIVE_XHR ||208      goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR) {209    return '';210  }211212  // The following blog post describes what PROG IDs to use to create the213  // XMLHTTP object in Internet Explorer:214  // http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx215  // However we do not (yet) fully trust that this will be OK for old versions216  // of IE on Win9x so we therefore keep the last 2.217  if (!this.ieProgId_ && typeof XMLHttpRequest == 'undefined' &&218      typeof ActiveXObject != 'undefined') {219    // Candidate Active X types.220    var ACTIVE_X_IDENTS = ['MSXML2.XMLHTTP.6.0', 'MSXML2.XMLHTTP.3.0',221                           'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP'];222    for (var i = 0; i < ACTIVE_X_IDENTS.length; i++) {223      var candidate = ACTIVE_X_IDENTS[i];224      /** @preserveTry */225      try {226        new ActiveXObject(candidate);227        // NOTE(user): cannot assign progid and return candidate in one line228        // because JSCompiler complaings: BUG 658126229        this.ieProgId_ = candidate;230        return candidate;231      } catch (e) {232        // do nothing; try next choice233      }234    }235236    // couldn't find any matches237    throw Error('Could not create ActiveXObject. ActiveX might be disabled,' +238                ' or MSXML might not be installed');239  }240241  return /** @type {string} */ (this.ieProgId_);242};243244245//Set the global factory to an instance of the default factory.246goog.net.XmlHttp.setGlobalFactory(new goog.net.DefaultXmlHttpFactory());