uniapp,h5

polling-xhr.js 8.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. exports.XHR = exports.Request = exports.BaseXHR = void 0;
  7. const polling_js_1 = require("./polling.js");
  8. const component_emitter_1 = require("@socket.io/component-emitter");
  9. const util_js_1 = require("../util.js");
  10. const globals_node_js_1 = require("../globals.node.js");
  11. const has_cors_js_1 = require("../contrib/has-cors.js");
  12. const debug_1 = __importDefault(require("debug")); // debug()
  13. const debug = (0, debug_1.default)("engine.io-client:polling"); // debug()
  14. function empty() { }
  15. class BaseXHR extends polling_js_1.Polling {
  16. /**
  17. * XHR Polling constructor.
  18. *
  19. * @param {Object} opts
  20. * @package
  21. */
  22. constructor(opts) {
  23. super(opts);
  24. if (typeof location !== "undefined") {
  25. const isSSL = "https:" === location.protocol;
  26. let port = location.port;
  27. // some user agents have empty `location.port`
  28. if (!port) {
  29. port = isSSL ? "443" : "80";
  30. }
  31. this.xd =
  32. (typeof location !== "undefined" &&
  33. opts.hostname !== location.hostname) ||
  34. port !== opts.port;
  35. }
  36. }
  37. /**
  38. * Sends data.
  39. *
  40. * @param {String} data to send.
  41. * @param {Function} called upon flush.
  42. * @private
  43. */
  44. doWrite(data, fn) {
  45. const req = this.request({
  46. method: "POST",
  47. data: data,
  48. });
  49. req.on("success", fn);
  50. req.on("error", (xhrStatus, context) => {
  51. this.onError("xhr post error", xhrStatus, context);
  52. });
  53. }
  54. /**
  55. * Starts a poll cycle.
  56. *
  57. * @private
  58. */
  59. doPoll() {
  60. debug("xhr poll");
  61. const req = this.request();
  62. req.on("data", this.onData.bind(this));
  63. req.on("error", (xhrStatus, context) => {
  64. this.onError("xhr poll error", xhrStatus, context);
  65. });
  66. this.pollXhr = req;
  67. }
  68. }
  69. exports.BaseXHR = BaseXHR;
  70. class Request extends component_emitter_1.Emitter {
  71. /**
  72. * Request constructor
  73. *
  74. * @param {Object} options
  75. * @package
  76. */
  77. constructor(createRequest, uri, opts) {
  78. super();
  79. this.createRequest = createRequest;
  80. (0, util_js_1.installTimerFunctions)(this, opts);
  81. this._opts = opts;
  82. this._method = opts.method || "GET";
  83. this._uri = uri;
  84. this._data = undefined !== opts.data ? opts.data : null;
  85. this._create();
  86. }
  87. /**
  88. * Creates the XHR object and sends the request.
  89. *
  90. * @private
  91. */
  92. _create() {
  93. var _a;
  94. const opts = (0, util_js_1.pick)(this._opts, "agent", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "autoUnref");
  95. opts.xdomain = !!this._opts.xd;
  96. const xhr = (this._xhr = this.createRequest(opts));
  97. try {
  98. debug("xhr open %s: %s", this._method, this._uri);
  99. xhr.open(this._method, this._uri, true);
  100. try {
  101. if (this._opts.extraHeaders) {
  102. // @ts-ignore
  103. xhr.setDisableHeaderCheck && xhr.setDisableHeaderCheck(true);
  104. for (let i in this._opts.extraHeaders) {
  105. if (this._opts.extraHeaders.hasOwnProperty(i)) {
  106. xhr.setRequestHeader(i, this._opts.extraHeaders[i]);
  107. }
  108. }
  109. }
  110. }
  111. catch (e) { }
  112. if ("POST" === this._method) {
  113. try {
  114. xhr.setRequestHeader("Content-type", "text/plain;charset=UTF-8");
  115. }
  116. catch (e) { }
  117. }
  118. try {
  119. xhr.setRequestHeader("Accept", "*/*");
  120. }
  121. catch (e) { }
  122. (_a = this._opts.cookieJar) === null || _a === void 0 ? void 0 : _a.addCookies(xhr);
  123. // ie6 check
  124. if ("withCredentials" in xhr) {
  125. xhr.withCredentials = this._opts.withCredentials;
  126. }
  127. if (this._opts.requestTimeout) {
  128. xhr.timeout = this._opts.requestTimeout;
  129. }
  130. xhr.onreadystatechange = () => {
  131. var _a;
  132. if (xhr.readyState === 3) {
  133. (_a = this._opts.cookieJar) === null || _a === void 0 ? void 0 : _a.parseCookies(
  134. // @ts-ignore
  135. xhr.getResponseHeader("set-cookie"));
  136. }
  137. if (4 !== xhr.readyState)
  138. return;
  139. if (200 === xhr.status || 1223 === xhr.status) {
  140. this._onLoad();
  141. }
  142. else {
  143. // make sure the `error` event handler that's user-set
  144. // does not throw in the same tick and gets caught here
  145. this.setTimeoutFn(() => {
  146. this._onError(typeof xhr.status === "number" ? xhr.status : 0);
  147. }, 0);
  148. }
  149. };
  150. debug("xhr data %s", this._data);
  151. xhr.send(this._data);
  152. }
  153. catch (e) {
  154. // Need to defer since .create() is called directly from the constructor
  155. // and thus the 'error' event can only be only bound *after* this exception
  156. // occurs. Therefore, also, we cannot throw here at all.
  157. this.setTimeoutFn(() => {
  158. this._onError(e);
  159. }, 0);
  160. return;
  161. }
  162. if (typeof document !== "undefined") {
  163. this._index = Request.requestsCount++;
  164. Request.requests[this._index] = this;
  165. }
  166. }
  167. /**
  168. * Called upon error.
  169. *
  170. * @private
  171. */
  172. _onError(err) {
  173. this.emitReserved("error", err, this._xhr);
  174. this._cleanup(true);
  175. }
  176. /**
  177. * Cleans up house.
  178. *
  179. * @private
  180. */
  181. _cleanup(fromError) {
  182. if ("undefined" === typeof this._xhr || null === this._xhr) {
  183. return;
  184. }
  185. this._xhr.onreadystatechange = empty;
  186. if (fromError) {
  187. try {
  188. this._xhr.abort();
  189. }
  190. catch (e) { }
  191. }
  192. if (typeof document !== "undefined") {
  193. delete Request.requests[this._index];
  194. }
  195. this._xhr = null;
  196. }
  197. /**
  198. * Called upon load.
  199. *
  200. * @private
  201. */
  202. _onLoad() {
  203. const data = this._xhr.responseText;
  204. if (data !== null) {
  205. this.emitReserved("data", data);
  206. this.emitReserved("success");
  207. this._cleanup();
  208. }
  209. }
  210. /**
  211. * Aborts the request.
  212. *
  213. * @package
  214. */
  215. abort() {
  216. this._cleanup();
  217. }
  218. }
  219. exports.Request = Request;
  220. Request.requestsCount = 0;
  221. Request.requests = {};
  222. /**
  223. * Aborts pending requests when unloading the window. This is needed to prevent
  224. * memory leaks (e.g. when using IE) and to ensure that no spurious error is
  225. * emitted.
  226. */
  227. if (typeof document !== "undefined") {
  228. // @ts-ignore
  229. if (typeof attachEvent === "function") {
  230. // @ts-ignore
  231. attachEvent("onunload", unloadHandler);
  232. }
  233. else if (typeof addEventListener === "function") {
  234. const terminationEvent = "onpagehide" in globals_node_js_1.globalThisShim ? "pagehide" : "unload";
  235. addEventListener(terminationEvent, unloadHandler, false);
  236. }
  237. }
  238. function unloadHandler() {
  239. for (let i in Request.requests) {
  240. if (Request.requests.hasOwnProperty(i)) {
  241. Request.requests[i].abort();
  242. }
  243. }
  244. }
  245. const hasXHR2 = (function () {
  246. const xhr = newRequest({
  247. xdomain: false,
  248. });
  249. return xhr && xhr.responseType !== null;
  250. })();
  251. /**
  252. * HTTP long-polling based on the built-in `XMLHttpRequest` object.
  253. *
  254. * Usage: browser
  255. *
  256. * @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
  257. */
  258. class XHR extends BaseXHR {
  259. constructor(opts) {
  260. super(opts);
  261. const forceBase64 = opts && opts.forceBase64;
  262. this.supportsBinary = hasXHR2 && !forceBase64;
  263. }
  264. request(opts = {}) {
  265. Object.assign(opts, { xd: this.xd }, this.opts);
  266. return new Request(newRequest, this.uri(), opts);
  267. }
  268. }
  269. exports.XHR = XHR;
  270. function newRequest(opts) {
  271. const xdomain = opts.xdomain;
  272. // XMLHttpRequest can be disabled on IE
  273. try {
  274. if ("undefined" !== typeof XMLHttpRequest && (!xdomain || has_cors_js_1.hasCORS)) {
  275. return new XMLHttpRequest();
  276. }
  277. }
  278. catch (e) { }
  279. if (!xdomain) {
  280. try {
  281. return new globals_node_js_1.globalThisShim[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP");
  282. }
  283. catch (e) { }
  284. }
  285. }