fetch.umd.js 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  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. var support = {
  7. searchParams: 'URLSearchParams' in self,
  8. iterable: 'Symbol' in self && 'iterator' in Symbol,
  9. blob:
  10. 'FileReader' in self &&
  11. 'Blob' in self &&
  12. (function() {
  13. try {
  14. new Blob();
  15. return true
  16. } catch (e) {
  17. return false
  18. }
  19. })(),
  20. formData: 'FormData' in self,
  21. arrayBuffer: 'ArrayBuffer' in self
  22. };
  23. function isDataView(obj) {
  24. return obj && DataView.prototype.isPrototypeOf(obj)
  25. }
  26. if (support.arrayBuffer) {
  27. var viewClasses = [
  28. '[object Int8Array]',
  29. '[object Uint8Array]',
  30. '[object Uint8ClampedArray]',
  31. '[object Int16Array]',
  32. '[object Uint16Array]',
  33. '[object Int32Array]',
  34. '[object Uint32Array]',
  35. '[object Float32Array]',
  36. '[object Float64Array]'
  37. ];
  38. var isArrayBufferView =
  39. ArrayBuffer.isView ||
  40. function(obj) {
  41. return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
  42. };
  43. }
  44. function normalizeName(name) {
  45. if (typeof name !== 'string') {
  46. name = String(name);
  47. }
  48. if (/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(name)) {
  49. throw new TypeError('Invalid character in header field name')
  50. }
  51. return name.toLowerCase()
  52. }
  53. function normalizeValue(value) {
  54. if (typeof value !== 'string') {
  55. value = String(value);
  56. }
  57. return value
  58. }
  59. // Build a destructive iterator for the value list
  60. function iteratorFor(items) {
  61. var iterator = {
  62. next: function() {
  63. var value = items.shift();
  64. return {done: value === undefined, value: value}
  65. }
  66. };
  67. if (support.iterable) {
  68. iterator[Symbol.iterator] = function() {
  69. return iterator
  70. };
  71. }
  72. return iterator
  73. }
  74. function Headers(headers) {
  75. this.map = {};
  76. if (headers instanceof Headers) {
  77. headers.forEach(function(value, name) {
  78. this.append(name, value);
  79. }, this);
  80. } else if (Array.isArray(headers)) {
  81. headers.forEach(function(header) {
  82. this.append(header[0], header[1]);
  83. }, this);
  84. } else if (headers) {
  85. Object.getOwnPropertyNames(headers).forEach(function(name) {
  86. this.append(name, headers[name]);
  87. }, this);
  88. }
  89. }
  90. Headers.prototype.append = function(name, value) {
  91. name = normalizeName(name);
  92. value = normalizeValue(value);
  93. var oldValue = this.map[name];
  94. this.map[name] = oldValue ? oldValue + ', ' + value : value;
  95. };
  96. Headers.prototype['delete'] = function(name) {
  97. delete this.map[normalizeName(name)];
  98. };
  99. Headers.prototype.get = function(name) {
  100. name = normalizeName(name);
  101. return this.has(name) ? this.map[name] : null
  102. };
  103. Headers.prototype.has = function(name) {
  104. return this.map.hasOwnProperty(normalizeName(name))
  105. };
  106. Headers.prototype.set = function(name, value) {
  107. this.map[normalizeName(name)] = normalizeValue(value);
  108. };
  109. Headers.prototype.forEach = function(callback, thisArg) {
  110. for (var name in this.map) {
  111. if (this.map.hasOwnProperty(name)) {
  112. callback.call(thisArg, this.map[name], name, this);
  113. }
  114. }
  115. };
  116. Headers.prototype.keys = function() {
  117. var items = [];
  118. this.forEach(function(value, name) {
  119. items.push(name);
  120. });
  121. return iteratorFor(items)
  122. };
  123. Headers.prototype.values = function() {
  124. var items = [];
  125. this.forEach(function(value) {
  126. items.push(value);
  127. });
  128. return iteratorFor(items)
  129. };
  130. Headers.prototype.entries = function() {
  131. var items = [];
  132. this.forEach(function(value, name) {
  133. items.push([name, value]);
  134. });
  135. return iteratorFor(items)
  136. };
  137. if (support.iterable) {
  138. Headers.prototype[Symbol.iterator] = Headers.prototype.entries;
  139. }
  140. function consumed(body) {
  141. if (body.bodyUsed) {
  142. return Promise.reject(new TypeError('Already read'))
  143. }
  144. body.bodyUsed = true;
  145. }
  146. function fileReaderReady(reader) {
  147. return new Promise(function(resolve, reject) {
  148. reader.onload = function() {
  149. resolve(reader.result);
  150. };
  151. reader.onerror = function() {
  152. reject(reader.error);
  153. };
  154. })
  155. }
  156. function readBlobAsArrayBuffer(blob) {
  157. var reader = new FileReader();
  158. var promise = fileReaderReady(reader);
  159. reader.readAsArrayBuffer(blob);
  160. return promise
  161. }
  162. function readBlobAsText(blob) {
  163. var reader = new FileReader();
  164. var promise = fileReaderReady(reader);
  165. reader.readAsText(blob);
  166. return promise
  167. }
  168. function readArrayBufferAsText(buf) {
  169. var view = new Uint8Array(buf);
  170. var chars = new Array(view.length);
  171. for (var i = 0; i < view.length; i++) {
  172. chars[i] = String.fromCharCode(view[i]);
  173. }
  174. return chars.join('')
  175. }
  176. function bufferClone(buf) {
  177. if (buf.slice) {
  178. return buf.slice(0)
  179. } else {
  180. var view = new Uint8Array(buf.byteLength);
  181. view.set(new Uint8Array(buf));
  182. return view.buffer
  183. }
  184. }
  185. function Body() {
  186. this.bodyUsed = false;
  187. this._initBody = function(body) {
  188. this._bodyInit = body;
  189. if (!body) {
  190. this._bodyText = '';
  191. } else if (typeof body === 'string') {
  192. this._bodyText = body;
  193. } else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
  194. this._bodyBlob = body;
  195. } else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
  196. this._bodyFormData = body;
  197. } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
  198. this._bodyText = body.toString();
  199. } else if (support.arrayBuffer && support.blob && isDataView(body)) {
  200. this._bodyArrayBuffer = bufferClone(body.buffer);
  201. // IE 10-11 can't handle a DataView body.
  202. this._bodyInit = new Blob([this._bodyArrayBuffer]);
  203. } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {
  204. this._bodyArrayBuffer = bufferClone(body);
  205. } else {
  206. this._bodyText = body = Object.prototype.toString.call(body);
  207. }
  208. if (!this.headers.get('content-type')) {
  209. if (typeof body === 'string') {
  210. this.headers.set('content-type', 'text/plain;charset=UTF-8');
  211. } else if (this._bodyBlob && this._bodyBlob.type) {
  212. this.headers.set('content-type', this._bodyBlob.type);
  213. } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
  214. this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
  215. }
  216. }
  217. };
  218. if (support.blob) {
  219. this.blob = function() {
  220. var rejected = consumed(this);
  221. if (rejected) {
  222. return rejected
  223. }
  224. if (this._bodyBlob) {
  225. return Promise.resolve(this._bodyBlob)
  226. } else if (this._bodyArrayBuffer) {
  227. return Promise.resolve(new Blob([this._bodyArrayBuffer]))
  228. } else if (this._bodyFormData) {
  229. throw new Error('could not read FormData body as blob')
  230. } else {
  231. return Promise.resolve(new Blob([this._bodyText]))
  232. }
  233. };
  234. this.arrayBuffer = function() {
  235. if (this._bodyArrayBuffer) {
  236. return consumed(this) || Promise.resolve(this._bodyArrayBuffer)
  237. } else {
  238. return this.blob().then(readBlobAsArrayBuffer)
  239. }
  240. };
  241. }
  242. this.text = function() {
  243. var rejected = consumed(this);
  244. if (rejected) {
  245. return rejected
  246. }
  247. if (this._bodyBlob) {
  248. return readBlobAsText(this._bodyBlob)
  249. } else if (this._bodyArrayBuffer) {
  250. return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))
  251. } else if (this._bodyFormData) {
  252. throw new Error('could not read FormData body as text')
  253. } else {
  254. return Promise.resolve(this._bodyText)
  255. }
  256. };
  257. if (support.formData) {
  258. this.formData = function() {
  259. return this.text().then(decode)
  260. };
  261. }
  262. this.json = function() {
  263. return this.text().then(JSON.parse)
  264. };
  265. return this
  266. }
  267. // HTTP methods whose capitalization should be normalized
  268. var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT'];
  269. function normalizeMethod(method) {
  270. var upcased = method.toUpperCase();
  271. return methods.indexOf(upcased) > -1 ? upcased : method
  272. }
  273. function Request(input, options) {
  274. options = options || {};
  275. var body = options.body;
  276. if (input instanceof Request) {
  277. if (input.bodyUsed) {
  278. throw new TypeError('Already read')
  279. }
  280. this.url = input.url;
  281. this.credentials = input.credentials;
  282. if (!options.headers) {
  283. this.headers = new Headers(input.headers);
  284. }
  285. this.method = input.method;
  286. this.mode = input.mode;
  287. this.signal = input.signal;
  288. if (!body && input._bodyInit != null) {
  289. body = input._bodyInit;
  290. input.bodyUsed = true;
  291. }
  292. } else {
  293. this.url = String(input);
  294. }
  295. this.credentials = options.credentials || this.credentials || 'same-origin';
  296. if (options.headers || !this.headers) {
  297. this.headers = new Headers(options.headers);
  298. }
  299. this.method = normalizeMethod(options.method || this.method || 'GET');
  300. this.mode = options.mode || this.mode || null;
  301. this.signal = options.signal || this.signal;
  302. this.referrer = null;
  303. if ((this.method === 'GET' || this.method === 'HEAD') && body) {
  304. throw new TypeError('Body not allowed for GET or HEAD requests')
  305. }
  306. this._initBody(body);
  307. }
  308. Request.prototype.clone = function() {
  309. return new Request(this, {body: this._bodyInit})
  310. };
  311. function decode(body) {
  312. var form = new FormData();
  313. body
  314. .trim()
  315. .split('&')
  316. .forEach(function(bytes) {
  317. if (bytes) {
  318. var split = bytes.split('=');
  319. var name = split.shift().replace(/\+/g, ' ');
  320. var value = split.join('=').replace(/\+/g, ' ');
  321. form.append(decodeURIComponent(name), decodeURIComponent(value));
  322. }
  323. });
  324. return form
  325. }
  326. function parseHeaders(rawHeaders) {
  327. var headers = new Headers();
  328. // Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space
  329. // https://tools.ietf.org/html/rfc7230#section-3.2
  330. var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ');
  331. preProcessedHeaders.split(/\r?\n/).forEach(function(line) {
  332. var parts = line.split(':');
  333. var key = parts.shift().trim();
  334. if (key) {
  335. var value = parts.join(':').trim();
  336. headers.append(key, value);
  337. }
  338. });
  339. return headers
  340. }
  341. Body.call(Request.prototype);
  342. function Response(bodyInit, options) {
  343. if (!options) {
  344. options = {};
  345. }
  346. this.type = 'default';
  347. this.status = options.status === undefined ? 200 : options.status;
  348. this.ok = this.status >= 200 && this.status < 300;
  349. this.statusText = 'statusText' in options ? options.statusText : 'OK';
  350. this.headers = new Headers(options.headers);
  351. this.url = options.url || '';
  352. this._initBody(bodyInit);
  353. }
  354. Body.call(Response.prototype);
  355. Response.prototype.clone = function() {
  356. return new Response(this._bodyInit, {
  357. status: this.status,
  358. statusText: this.statusText,
  359. headers: new Headers(this.headers),
  360. url: this.url
  361. })
  362. };
  363. Response.error = function() {
  364. var response = new Response(null, {status: 0, statusText: ''});
  365. response.type = 'error';
  366. return response
  367. };
  368. var redirectStatuses = [301, 302, 303, 307, 308];
  369. Response.redirect = function(url, status) {
  370. if (redirectStatuses.indexOf(status) === -1) {
  371. throw new RangeError('Invalid status code')
  372. }
  373. return new Response(null, {status: status, headers: {location: url}})
  374. };
  375. exports.DOMException = self.DOMException;
  376. try {
  377. new exports.DOMException();
  378. } catch (err) {
  379. exports.DOMException = function(message, name) {
  380. this.message = message;
  381. this.name = name;
  382. var error = Error(message);
  383. this.stack = error.stack;
  384. };
  385. exports.DOMException.prototype = Object.create(Error.prototype);
  386. exports.DOMException.prototype.constructor = exports.DOMException;
  387. }
  388. function fetch(input, init) {
  389. return new Promise(function(resolve, reject) {
  390. var request = new Request(input, init);
  391. if (request.signal && request.signal.aborted) {
  392. return reject(new exports.DOMException('Aborted', 'AbortError'))
  393. }
  394. var xhr = new XMLHttpRequest();
  395. function abortXhr() {
  396. xhr.abort();
  397. }
  398. xhr.onload = function() {
  399. var options = {
  400. status: xhr.status,
  401. statusText: xhr.statusText,
  402. headers: parseHeaders(xhr.getAllResponseHeaders() || '')
  403. };
  404. options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL');
  405. var body = 'response' in xhr ? xhr.response : xhr.responseText;
  406. resolve(new Response(body, options));
  407. };
  408. xhr.onerror = function() {
  409. reject(new TypeError('Network request failed'));
  410. };
  411. xhr.ontimeout = function() {
  412. reject(new TypeError('Network request failed'));
  413. };
  414. xhr.onabort = function() {
  415. reject(new exports.DOMException('Aborted', 'AbortError'));
  416. };
  417. xhr.open(request.method, request.url, true);
  418. if (request.credentials === 'include') {
  419. xhr.withCredentials = true;
  420. } else if (request.credentials === 'omit') {
  421. xhr.withCredentials = false;
  422. }
  423. if ('responseType' in xhr && support.blob) {
  424. xhr.responseType = 'blob';
  425. }
  426. request.headers.forEach(function(value, name) {
  427. xhr.setRequestHeader(name, value);
  428. });
  429. if (request.signal) {
  430. request.signal.addEventListener('abort', abortXhr);
  431. xhr.onreadystatechange = function() {
  432. // DONE (success or failure)
  433. if (xhr.readyState === 4) {
  434. request.signal.removeEventListener('abort', abortXhr);
  435. }
  436. };
  437. }
  438. xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit);
  439. })
  440. }
  441. fetch.polyfill = true;
  442. if (!self.fetch) {
  443. self.fetch = fetch;
  444. self.Headers = Headers;
  445. self.Request = Request;
  446. self.Response = Response;
  447. }
  448. exports.Headers = Headers;
  449. exports.Request = Request;
  450. exports.Response = Response;
  451. exports.fetch = fetch;
  452. Object.defineProperty(exports, '__esModule', { value: true });
  453. })));