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 at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// 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 and 13// limitations under the License. 14 15/** 16 * @fileoverview Low level handling of XMLHttpRequest. 17 */ 18 19goog.provide('goog.net.DefaultXmlHttpFactory'); 20goog.provide('goog.net.XmlHttp'); 21goog.provide('goog.net.XmlHttp.OptionType'); 22goog.provide('goog.net.XmlHttp.ReadyState'); 23 24goog.require('goog.net.WrapperXmlHttpFactory'); 25goog.require('goog.net.XmlHttpFactory'); 26 27 28/** 29 * Static class for creating XMLHttpRequest objects. 30 * @return {!(XMLHttpRequest|GearsHttpRequest)} A new XMLHttpRequest object. 31 */ 32goog.net.XmlHttp = function() { 33 return goog.net.XmlHttp.factory_.createInstance(); 34}; 35 36 37/** 38 * Gets the options to use with the XMLHttpRequest objects obtained using 39 * the static methods. 40 * @return {Object} The options. 41 */ 42goog.net.XmlHttp.getOptions = function() { 43 return goog.net.XmlHttp.factory_.getOptions(); 44}; 45 46 47/** 48 * Type of options that an XmlHttp object can have. 49 * @enum {number} 50 */ 51goog.net.XmlHttp.OptionType = { 52 /** 53 * Whether a goog.nullFunction should be used to clear the onreadystatechange 54 * handler instead of null. 55 */ 56 USE_NULL_FUNCTION: 0, 57 58 /** 59 * NOTE(user): In IE if send() errors on a *local* request the readystate 60 * is still changed to COMPLETE. We need to ignore it and allow the 61 * try/catch around send() to pick up the error. 62 */ 63 LOCAL_REQUEST_ERROR: 1 64}; 65 66 67/** 68 * Status constants for XMLHTTP, matches: 69 * http://msdn.microsoft.com/library/default.asp?url=/library/ 70 * en-us/xmlsdk/html/0e6a34e4-f90c-489d-acff-cb44242fafc6.asp 71 * @enum {number} 72 */ 73goog.net.XmlHttp.ReadyState = { 74 /** 75 * Constant for when xmlhttprequest.readyState is uninitialized 76 */ 77 UNINITIALIZED: 0, 78 79 /** 80 * Constant for when xmlhttprequest.readyState is loading. 81 */ 82 LOADING: 1, 83 84 /** 85 * Constant for when xmlhttprequest.readyState is loaded. 86 */ 87 LOADED: 2, 88 89 /** 90 * Constant for when xmlhttprequest.readyState is in an interactive state. 91 */ 92 INTERACTIVE: 3, 93 94 /** 95 * Constant for when xmlhttprequest.readyState is completed 96 */ 97 COMPLETE: 4 98}; 99 100 101/** 102 * The global factory instance for creating XMLHttpRequest objects. 103 * @type {goog.net.XmlHttpFactory} 104 * @private 105 */ 106goog.net.XmlHttp.factory_; 107 108 109/** 110 * Sets the factories for creating XMLHttpRequest objects and their options. 111 * @param {Function} factory The factory for XMLHttpRequest objects. 112 * @param {Function} optionsFactory The factory for options. 113 * @deprecated Use setGlobalFactory instead. 114 */ 115goog.net.XmlHttp.setFactory = function(factory, optionsFactory) { 116 goog.net.XmlHttp.setGlobalFactory(new goog.net.WrapperXmlHttpFactory( 117 (/** @type {function() : !(XMLHttpRequest|GearsHttpRequest)} */ factory), 118 (/** @type {function() : !Object}*/ optionsFactory))); 119}; 120 121 122/** 123 * Sets the global factory object. 124 * @param {!goog.net.XmlHttpFactory} factory New global factory object. 125 */ 126goog.net.XmlHttp.setGlobalFactory = function(factory) { 127 goog.net.XmlHttp.factory_ = factory; 128}; 129 130 131 132/** 133 * Default factory to use when creating xhr objects. You probably shouldn't be 134 * instantiating this directly, but rather using it via goog.net.XmlHttp. 135 * @extends {goog.net.XmlHttpFactory} 136 * @constructor 137 */ 138goog.net.DefaultXmlHttpFactory = function() { 139 goog.net.XmlHttpFactory.call(this); 140}; 141goog.inherits(goog.net.DefaultXmlHttpFactory, goog.net.XmlHttpFactory); 142 143 144/** @inheritDoc */ 145goog.net.DefaultXmlHttpFactory.prototype.createInstance = function() { 146 var progId = this.getProgId_(); 147 if (progId) { 148 return new ActiveXObject(progId); 149 } else { 150 return new XMLHttpRequest(); 151 } 152}; 153 154 155/** @inheritDoc */ 156goog.net.DefaultXmlHttpFactory.prototype.internalGetOptions = function() { 157 var progId = this.getProgId_(); 158 var options = {}; 159 if (progId) { 160 options[goog.net.XmlHttp.OptionType.USE_NULL_FUNCTION] = true; 161 options[goog.net.XmlHttp.OptionType.LOCAL_REQUEST_ERROR] = true; 162 } 163 return options; 164}; 165 166 167/** 168 * The ActiveX PROG ID string to use to create xhr's in IE. Lazily initialized. 169 * @type {?string} 170 * @private 171 */ 172goog.net.DefaultXmlHttpFactory.prototype.ieProgId_ = null; 173 174 175/** 176 * Initialize the private state used by other functions. 177 * @return {string} The ActiveX PROG ID string to use to create xhr's in IE. 178 * @private 179 */ 180goog.net.DefaultXmlHttpFactory.prototype.getProgId_ = function() { 181 // The following blog post describes what PROG IDs to use to create the 182 // XMLHTTP object in Internet Explorer: 183 // http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx 184 // However we do not (yet) fully trust that this will be OK for old versions 185 // of IE on Win9x so we therefore keep the last 2. 186 if (!this.ieProgId_ && typeof XMLHttpRequest == 'undefined' && 187 typeof ActiveXObject != 'undefined') { 188 // Candidate Active X types. 189 var ACTIVE_X_IDENTS = ['MSXML2.XMLHTTP.6.0', 'MSXML2.XMLHTTP.3.0', 190 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP']; 191 for (var i = 0; i < ACTIVE_X_IDENTS.length; i++) { 192 var candidate = ACTIVE_X_IDENTS[i]; 193 /** @preserveTry */ 194 try { 195 new ActiveXObject(candidate); 196 // NOTE(user): cannot assign progid and return candidate in one line 197 // because JSCompiler complaings: BUG 658126 198 this.ieProgId_ = candidate; 199 return candidate; 200 } catch (e) { 201 // do nothing; try next choice 202 } 203 } 204 205 // couldn't find any matches 206 throw Error('Could not create ActiveXObject. ActiveX might be disabled,' + 207 ' or MSXML might not be installed'); 208 } 209 210 return /** @type {string} */ (this.ieProgId_); 211}; 212 213 214//Set the global factory to an instance of the default factory. 215goog.net.XmlHttp.setGlobalFactory(new goog.net.DefaultXmlHttpFactory()); 216