fetch.umd.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  3. typeof define === 'function' && define.amd ? define(['exports'], factory) :
  4. (factory((global.WHATWGFetch = {})));
  5. }(this, (function (exports) { 'use strict';
  6. /* eslint-disable no-prototype-builtins */
  7. var g =
  8. (typeof globalThis !== 'undefined' && globalThis) ||
  9. (typeof self !== 'undefined' && self) ||
  10. // eslint-disable-next-line no-undef
  11. (typeof global !== 'undefined' && global) ||
  12. {};
  13. var support = {
  14. searchParams: 'URLSearchParams' in g,
  15. iterable: 'Symbol' in g && 'iterator' in Symbol,
  16. blob:
  17. 'FileReader' in g &&
  18. 'Blob' in g &&
  19. (function() {
  20. try {
  21. new Blob();
  22. return true
  23. } catch (e) {
  24. return false
  25. }
  26. })(),
  27. formData: 'FormData' in g,
  28. arrayBuffer: 'ArrayBuffer' in g
  29. };
  30. function isDataView(obj) {
  31. return obj && DataView.prototype.isPrototypeOf(obj)
  32. }
  33. if (support.arrayBuffer) {
  34. var viewClasses = [
  35. '[object Int8Array]',
  36. '[object Uint8Array]',
  37. '[object Uint8ClampedArray]',
  38. '[object Int16Array]',
  39. '[object Uint16Array]',
  40. '[object Int32Array]',
  41. '[object Uint32Array]',
  42. '[object Float32Array]',
  43. '[object Float64Array]'
  44. ];
  45. var isArrayBufferView =
  46. ArrayBuffer.isView ||
  47. function(obj) {
  48. return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
  49. };
  50. }
  51. function normalizeName(name) {
  52. if (typeof name !== 'string') {
  53. name = String(name);
  54. }
  55. if (/[^a-z0-9\-#$%&'*+.^_`|~!]/i.test(name) || name === '') {
  56. throw new TypeError('Invalid character in header field name: "' + name + '"')
  57. }
  58. return name.toLowerCase()
  59. }
  60. function normalizeValue(value) {
  61. if (typeof value !== 'string') {
  62. value = String(value);
  63. }
  64. return value
  65. }
  66. // Build a destructive iterator for the value list
  67. function iteratorFor(items) {
  68. var iterator = {
  69. next: function() {
  70. var value = items.shift();
  71. return {done: value === undefined, value: value}
  72. }
  73. };
  74. if (support.iterable) {
  75. iterator[Symbol.iterator] = function() {
  76. return iterator
  77. };
  78. }
  79. return iterator
  80. }
  81. function Headers(headers) {
  82. this.map = {};
  83. if (headers instanceof Headers) {
  84. headers.forEach(function(value, name) {
  85. this.append(name, value);
  86. }, this);
  87. } else if (Array.isArray(headers)) {
  88. headers.forEach(function(header) {
  89. if (header.length != 2) {
  90. throw new TypeError('Headers constructor: expected name/value pair to be length 2, found' + header.length)
  91. }
  92. this.append(header[0], header[1]);
  93. }, this);
  94. } else if (headers) {
  95. Object.getOwnPropertyNames(headers).forEach(function(name) {
  96. this.append(name, headers[name]);
  97. }, this);
  98. }
  99. }
  100. Headers.prototype.append = function(name, value) {
  101. name = normalizeName(name);
  102. value = normalizeValue(value);
  103. var oldValue = this.map[name];
  104. this.map[name] = oldValue ? oldValue + ', ' + value : value;
  105. };
  106. Headers.prototype['delete'] = function(name) {
  107. delete this.map[normalizeName(name)];
  108. };
  109. Headers.prototype.get = function(name) {
  110. name = normalizeName(name);
  111. return this.has(name) ? this.map[name] : null
  112. };
  113. Headers.prototype.has = function(name) {
  114. return this.map.hasOwnProperty(normalizeName(name))
  115. };
  116. Headers.prototype.set = function(name, value) {
  117. this.map[normalizeName(name)] = normalizeValue(value);
  118. };
  119. Headers.prototype.forEach = function(callback, thisArg) {
  120. for (var name in this.map) {
  121. if (this.map.hasOwnProperty(name)) {
  122. callback.call(thisArg, this.map[name], name, this);
  123. }
  124. }
  125. };
  126. Headers.prototype.keys = function() {
  127. var items = [];
  128. this.forEach(function(value, name) {
  129. items.push(name);
  130. });
  131. return iteratorFor(items)
  132. };
  133. Headers.prototype.values = function() {
  134. var items = [];
  135. this.forEach(function(value) {
  136. items.push(value);
  137. });
  138. return iteratorFor(items)
  139. };
  140. Headers.prototype.entries = function() {
  141. var items = [];
  142. this.forEach(function(value, name) {
  143. items.push([name, value]);
  144. });
  145. return iteratorFor(items)
  146. };
  147. if (support.iterable) {
  148. Headers.prototype[Symbol.iterator] = Headers.prototype.entries;
  149. }
  150. function consumed(body) {
  151. if (body._noBody) return
  152. if (body.bodyUsed) {
  153. return Promise.reject(new TypeError('Already read'))
  154. }
  155. body.bodyUsed = true;
  156. }
  157. function fileReaderReady(reader) {
  158. return new Promise(function(resolve, reject) {
  159. reader.onload = function() {
  160. resolve(reader.result);
  161. };
  162. reader.onerror = function() {
  163. reject(reader.error);
  164. };
  165. })
  166. }
  167. function readBlobAsArrayBuffer(blob) {
  168. var reader = new FileReader();
  169. var promise = fileReaderReady(reader);
  170. reader.readAsArrayBuffer(blob);
  171. return promise
  172. }
  173. function readBlobAsText(blob) {
  174. var reader = new FileReader();
  175. var promise = fileReaderReady(reader);
  176. var match = /charset=([A-Za-z0-9_-]+)/.exec(blob.type);
  177. var encoding = match ? match[1] : 'utf-8';
  178. reader.readAsText(blob, encoding);
  179. return promise
  180. }
  181. function readArrayBufferAsText(buf) {
  182. var view = new Uint8Array(buf);
  183. var chars = new Array(view.length);
  184. for (var i = 0; i < view.length; i++) {
  185. chars[i] = String.fromCharCode(view[i]);
  186. }
  187. return chars.join('')
  188. }
  189. function bufferClone(buf) {
  190. if (buf.slice) {
  191. return buf.slice(0)
  192. } else {
  193. var view = new Uint8Array(buf.byteLength);
  194. view.set(new Uint8Array(buf));
  195. return view.buffer
  196. }
  197. }
  198. function Body() {
  199. this.bodyUsed = false;
  200. this._initBody = function(body) {
  201. /*
  202. fetch-mock wraps the Response object in an ES6 Proxy to
  203. provide useful test harness features such as flush. However, on
  204. ES5 browsers without fetch or Proxy support pollyfills must be used;
  205. the proxy-pollyfill is unable to proxy an attribute unless it exists
  206. on the object before the Proxy is created. This change ensures
  207. Response.bodyUsed exists on the instance, while maintaining the
  208. semantic of setting Request.bodyUsed in the constructor before
  209. _initBody is called.
  210. */
  211. // eslint-disable-next-line no-self-assign
  212. this.bodyUsed = this.bodyUsed;
  213. this._bodyInit = body;
  214. if (!body) {
  215. this._noBody = true;
  216. this._bodyText = '';
  217. } else if (typeof body === 'string') {
  218. this._bodyText = body;
  219. } else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
  220. this._bodyBlob = body;
  221. } else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
  222. this._bodyFormData = body;
  223. } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
  224. this._bodyText = body.toString();
  225. } else if (support.arrayBuffer && support.blob && isDataView(body)) {
  226. this._bodyArrayBuffer = bufferClone(body.buffer);
  227. // IE 10-11 can't handle a DataView body.
  228. this._bodyInit = new Blob([this._bodyArrayBuffer]);
  229. } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {
  230. this._bodyArrayBuffer = bufferClone(body);
  231. } else {
  232. this._bodyText = body = Object.prototype.toString.call(body);
  233. }
  234. if (!this.headers.get('content-type')) {
  235. if (typeof body === 'string') {
  236. this.headers.set('content-type', 'text/plain;charset=UTF-8');
  237. } else if (this._bodyBlob && this._bodyBlob.type) {
  238. this.headers.set('content-type', this._bodyBlob.type);
  239. } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
  240. this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
  241. }
  242. }
  243. };
  244. if (support.blob) {
  245. this.blob = function() {
  246. var rejected = consumed(this);
  247. if (rejected) {
  248. return rejected
  249. }
  250. if (this._bodyBlob) {
  251. return Promise.resolve(this._bodyBlob)
  252. } else if (this._bodyArrayBuffer) {
  253. return Promise.resolve(new Blob([this._bodyArrayBuffer]))
  254. } else if (this._bodyFormData) {
  255. throw new Error('could not read FormData body as blob')
  256. } else {
  257. return Promise.resolve(new Blob([this._bodyText]))
  258. }
  259. };
  260. }
  261. this.arrayBuffer = function() {
  262. if (this._bodyArrayBuffer) {
  263. var isConsumed = consumed(this);
  264. if (isConsumed) {
  265. return isConsumed
  266. } else if (ArrayBuffer.isView(this._bodyArrayBuffer)) {
  267. return Promise.resolve(
  268. this._bodyArrayBuffer.buffer.slice(
  269. this._bodyArrayBuffer.byteOffset,
  270. this._bodyArrayBuffer.byteOffset + this._bodyArrayBuffer.byteLength
  271. )
  272. )
  273. } else {
  274. return Promise.resolve(this._bodyArrayBuffer)
  275. }
  276. } else if (support.blob) {
  277. return this.blob().then(readBlobAsArrayBuffer)
  278. } else {
  279. throw new Error('could not read as ArrayBuffer')
  280. }
  281. };
  282. this.text = function() {
  283. var rejected = consumed(this);
  284. if (rejected) {
  285. return rejected
  286. }
  287. if (this._bodyBlob) {
  288. return readBlobAsText(this._bodyBlob)
  289. } else if (this._bodyArrayBuffer) {
  290. return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))
  291. } else if (this._bodyFormData) {
  292. throw new Error('could not read FormData body as text')
  293. } else {
  294. return Promise.resolve(this._bodyText)
  295. }
  296. };
  297. if (support.formData) {
  298. this.formData = function() {
  299. return this.text().then(decode)
  300. };
  301. }
  302. this.json = function() {
  303. return this.text().then(JSON.parse)
  304. };
  305. return this
  306. }
  307. // HTTP methods whose capitalization should be normalized
  308. var methods = ['CONNECT', 'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PATCH', 'POST', 'PUT', 'TRACE'];
  309. function normalizeMethod(method) {
  310. var upcased = method.toUpperCase();
  311. return methods.indexOf(upcased) > -1 ? upcased : method
  312. }
  313. function Request(input, options) {
  314. if (!(this instanceof Request)) {
  315. throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.')
  316. }
  317. options = options || {};
  318. var body = options.body;
  319. if (input instanceof Request) {
  320. if (input.bodyUsed) {
  321. throw new TypeError('Already read')
  322. }
  323. this.url = input.url;
  324. this.credentials = input.credentials;
  325. if (!options.headers) {
  326. this.headers = new Headers(input.headers);
  327. }
  328. this.method = input.method;
  329. this.mode = input.mode;
  330. this.signal = input.signal;
  331. if (!body && input._bodyInit != null) {
  332. body = input._bodyInit;
  333. input.bodyUsed = true;
  334. }
  335. } else {
  336. this.url = String(input);
  337. }
  338. this.credentials = options.credentials || this.credentials || 'same-origin';
  339. if (options.headers || !this.headers) {
  340. this.headers = new Headers(options.headers);
  341. }
  342. this.method = normalizeMethod(options.method || this.method || 'GET');
  343. this.mode = options.mode || this.mode || null;
  344. this.signal = options.signal || this.signal || (function () {
  345. if ('AbortController' in g) {
  346. var ctrl = new AbortController();
  347. return ctrl.signal;
  348. }
  349. }());
  350. this.referrer = null;
  351. if ((this.method === 'GET' || this.method === 'HEAD') && body) {
  352. throw new TypeError('Body not allowed for GET or HEAD requests')
  353. }
  354. this._initBody(body);
  355. if (this.method === 'GET' || this.method === 'HEAD') {
  356. if (options.cache === 'no-store' || options.cache === 'no-cache') {
  357. // Search for a '_' parameter in the query string
  358. var reParamSearch = /([?&])_=[^&]*/;
  359. if (reParamSearch.test(this.url)) {
  360. // If it already exists then set the value with the current time
  361. this.url = this.url.replace(reParamSearch, '$1_=' + new Date().getTime());
  362. } else {
  363. // Otherwise add a new '_' parameter to the end with the current time
  364. var reQueryString = /\?/;
  365. this.url += (reQueryString.test(this.url) ? '&' : '?') + '_=' + new Date().getTime();
  366. }
  367. }
  368. }
  369. }
  370. Request.prototype.clone = function() {
  371. return new Request(this, {body: this._bodyInit})
  372. };
  373. function decode(body) {
  374. var form = new FormData();
  375. body
  376. .trim()
  377. .split('&')
  378. .forEach(function(bytes) {
  379. if (bytes) {
  380. var split = bytes.split('=');
  381. var name = split.shift().replace(/\+/g, ' ');
  382. var value = split.join('=').replace(/\+/g, ' ');
  383. form.append(decodeURIComponent(name), decodeURIComponent(value));
  384. }
  385. });
  386. return form
  387. }
  388. function parseHeaders(rawHeaders) {
  389. var headers = new Headers();
  390. // Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space
  391. // https://tools.ietf.org/html/rfc7230#section-3.2
  392. var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ');
  393. // Avoiding split via regex to work around a common IE11 bug with the core-js 3.6.0 regex polyfill
  394. // https://github.com/github/fetch/issues/748
  395. // https://github.com/zloirock/core-js/issues/751
  396. preProcessedHeaders
  397. .split('\r')
  398. .map(function(header) {
  399. return header.indexOf('\n') === 0 ? header.substr(1, header.length) : header
  400. })
  401. .forEach(function(line) {
  402. var parts = line.split(':');
  403. var key = parts.shift().trim();
  404. if (key) {
  405. var value = parts.join(':').trim();
  406. try {
  407. headers.append(key, value);
  408. } catch (error) {
  409. console.warn('Response ' + error.message);
  410. }
  411. }
  412. });
  413. return headers
  414. }
  415. Body.call(Request.prototype);
  416. function Response(bodyInit, options) {
  417. if (!(this instanceof Response)) {
  418. throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.')
  419. }
  420. if (!options) {
  421. options = {};
  422. }
  423. this.type = 'default';
  424. this.status = options.status === undefined ? 200 : options.status;
  425. if (this.status < 200 || this.status > 599) {
  426. throw new RangeError("Failed to construct 'Response': The status provided (0) is outside the range [200, 599].")
  427. }
  428. this.ok = this.status >= 200 && this.status < 300;
  429. this.statusText = options.statusText === undefined ? '' : '' + options.statusText;
  430. this.headers = new Headers(options.headers);
  431. this.url = options.url || '';
  432. this._initBody(bodyInit);
  433. }
  434. Body.call(Response.prototype);
  435. Response.prototype.clone = function() {
  436. return new Response(this._bodyInit, {
  437. status: this.status,
  438. statusText: this.statusText,
  439. headers: new Headers(this.headers),
  440. url: this.url
  441. })
  442. };
  443. Response.error = function() {
  444. var response = new Response(null, {status: 200, statusText: ''});
  445. response.status = 0;
  446. response.type = 'error';
  447. return response
  448. };
  449. var redirectStatuses = [301, 302, 303, 307, 308];
  450. Response.redirect = function(url, status) {
  451. if (redirectStatuses.indexOf(status) === -1) {
  452. throw new RangeError('Invalid status code')
  453. }
  454. return new Response(null, {status: status, headers: {location: url}})
  455. };
  456. exports.DOMException = g.DOMException;
  457. try {
  458. new exports.DOMException();
  459. } catch (err) {
  460. exports.DOMException = function(message, name) {
  461. this.message = message;
  462. this.name = name;
  463. var error = Error(message);
  464. this.stack = error.stack;
  465. };
  466. exports.DOMException.prototype = Object.create(Error.prototype);
  467. exports.DOMException.prototype.constructor = exports.DOMException;
  468. }
  469. function fetch(input, init) {
  470. return new Promise(function(resolve, reject) {
  471. var request = new Request(input, init);
  472. if (request.signal && request.signal.aborted) {
  473. return reject(new exports.DOMException('Aborted', 'AbortError'))
  474. }
  475. var xhr = new XMLHttpRequest();
  476. function abortXhr() {
  477. xhr.abort();
  478. }
  479. xhr.onload = function() {
  480. var options = {
  481. statusText: xhr.statusText,
  482. headers: parseHeaders(xhr.getAllResponseHeaders() || '')
  483. };
  484. // This check if specifically for when a user fetches a file locally from the file system
  485. // Only if the status is out of a normal range
  486. if (request.url.startsWith('file://') && (xhr.status < 200 || xhr.status > 599)) {
  487. options.status = 200;
  488. } else {
  489. options.status = xhr.status;
  490. }
  491. options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL');
  492. var body = 'response' in xhr ? xhr.response : xhr.responseText;
  493. setTimeout(function() {
  494. resolve(new Response(body, options));
  495. }, 0);
  496. };
  497. xhr.onerror = function() {
  498. setTimeout(function() {
  499. reject(new TypeError('Network request failed'));
  500. }, 0);
  501. };
  502. xhr.ontimeout = function() {
  503. setTimeout(function() {
  504. reject(new TypeError('Network request failed'));
  505. }, 0);
  506. };
  507. xhr.onabort = function() {
  508. setTimeout(function() {
  509. reject(new exports.DOMException('Aborted', 'AbortError'));
  510. }, 0);
  511. };
  512. function fixUrl(url) {
  513. try {
  514. return url === '' && g.location.href ? g.location.href : url
  515. } catch (e) {
  516. return url
  517. }
  518. }
  519. xhr.open(request.method, fixUrl(request.url), true);
  520. if (request.credentials === 'include') {
  521. xhr.withCredentials = true;
  522. } else if (request.credentials === 'omit') {
  523. xhr.withCredentials = false;
  524. }
  525. if ('responseType' in xhr) {
  526. if (support.blob) {
  527. xhr.responseType = 'blob';
  528. } else if (
  529. support.arrayBuffer
  530. ) {
  531. xhr.responseType = 'arraybuffer';
  532. }
  533. }
  534. if (init && typeof init.headers === 'object' && !(init.headers instanceof Headers || (g.Headers && init.headers instanceof g.Headers))) {
  535. var names = [];
  536. Object.getOwnPropertyNames(init.headers).forEach(function(name) {
  537. names.push(normalizeName(name));
  538. xhr.setRequestHeader(name, normalizeValue(init.headers[name]));
  539. });
  540. request.headers.forEach(function(value, name) {
  541. if (names.indexOf(name) === -1) {
  542. xhr.setRequestHeader(name, value);
  543. }
  544. });
  545. } else {
  546. request.headers.forEach(function(value, name) {
  547. xhr.setRequestHeader(name, value);
  548. });
  549. }
  550. if (request.signal) {
  551. request.signal.addEventListener('abort', abortXhr);
  552. xhr.onreadystatechange = function() {
  553. // DONE (success or failure)
  554. if (xhr.readyState === 4) {
  555. request.signal.removeEventListener('abort', abortXhr);
  556. }
  557. };
  558. }
  559. xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit);
  560. })
  561. }
  562. fetch.polyfill = true;
  563. if (!g.fetch) {
  564. g.fetch = fetch;
  565. g.Headers = Headers;
  566. g.Request = Request;
  567. g.Response = Response;
  568. }
  569. exports.Headers = Headers;
  570. exports.Request = Request;
  571. exports.Response = Response;
  572. exports.fetch = fetch;
  573. Object.defineProperty(exports, '__esModule', { value: true });
  574. })));