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