xmlhttp.js 7.0 KB

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