249 lines
7 KiB
JavaScript
249 lines
7 KiB
JavaScript
// 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());
|