fly.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. /******/ (function(modules) { // webpackBootstrap
  2. /******/ // The module cache
  3. /******/ var installedModules = {};
  4. /******/
  5. /******/ // The require function
  6. /******/ function __webpack_require__(moduleId) {
  7. /******/
  8. /******/ // Check if module is in cache
  9. /******/ if(installedModules[moduleId]) {
  10. /******/ return installedModules[moduleId].exports;
  11. /******/ }
  12. /******/ // Create a new module (and put it into the cache)
  13. /******/ var module = installedModules[moduleId] = {
  14. /******/ i: moduleId,
  15. /******/ l: false,
  16. /******/ exports: {}
  17. /******/ };
  18. /******/
  19. /******/ // Execute the module function
  20. /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  21. /******/
  22. /******/ // Flag the module as loaded
  23. /******/ module.l = true;
  24. /******/
  25. /******/ // Return the exports of the module
  26. /******/ return module.exports;
  27. /******/ }
  28. /******/
  29. /******/
  30. /******/ // expose the modules object (__webpack_modules__)
  31. /******/ __webpack_require__.m = modules;
  32. /******/
  33. /******/ // expose the module cache
  34. /******/ __webpack_require__.c = installedModules;
  35. /******/
  36. /******/ // identity function for calling harmony imports with the correct context
  37. /******/ __webpack_require__.i = function(value) { return value; };
  38. /******/
  39. /******/ // define getter function for harmony exports
  40. /******/ __webpack_require__.d = function(exports, name, getter) {
  41. /******/ if(!__webpack_require__.o(exports, name)) {
  42. /******/ Object.defineProperty(exports, name, {
  43. /******/ configurable: false,
  44. /******/ enumerable: true,
  45. /******/ get: getter
  46. /******/ });
  47. /******/ }
  48. /******/ };
  49. /******/
  50. /******/ // getDefaultExport function for compatibility with non-harmony modules
  51. /******/ __webpack_require__.n = function(module) {
  52. /******/ var getter = module && module.__esModule ?
  53. /******/ function getDefault() { return module['default']; } :
  54. /******/ function getModuleExports() { return module; };
  55. /******/ __webpack_require__.d(getter, 'a', getter);
  56. /******/ return getter;
  57. /******/ };
  58. /******/
  59. /******/ // Object.prototype.hasOwnProperty.call
  60. /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
  61. /******/
  62. /******/ // __webpack_public_path__
  63. /******/ __webpack_require__.p = "";
  64. /******/
  65. /******/ // Load entry module and return exports
  66. /******/ return __webpack_require__(__webpack_require__.s = 5);
  67. /******/ })
  68. /************************************************************************/
  69. /******/ ({
  70. /***/ 1:
  71. /***/ (function(module, exports, __webpack_require__) {
  72. "use strict";
  73. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  74. module.exports = {
  75. type: function type(ob) {
  76. return Object.prototype.toString.call(ob).slice(8, -1).toLowerCase();
  77. },
  78. isObject: function isObject(ob, real) {
  79. if (real) {
  80. return this.type(ob) === "object";
  81. } else {
  82. return ob && (typeof ob === 'undefined' ? 'undefined' : _typeof(ob)) === 'object';
  83. }
  84. },
  85. isFormData: function isFormData(val) {
  86. return typeof FormData !== 'undefined' && val instanceof FormData;
  87. },
  88. trim: function trim(str) {
  89. return str.replace(/(^\s*)|(\s*$)/g, '');
  90. },
  91. encode: function encode(val) {
  92. return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']');
  93. },
  94. formatParams: function formatParams(data) {
  95. var str = "";
  96. var first = true;
  97. var that = this;
  98. if (!this.isObject(data)) {
  99. return data;
  100. }
  101. function _encode(sub, path) {
  102. var encode = that.encode;
  103. var type = that.type(sub);
  104. if (type == "array") {
  105. sub.forEach(function (e, i) {
  106. if (!that.isObject(e)) i = "";
  107. _encode(e, path + ('%5B' + i + '%5D'));
  108. });
  109. } else if (type == "object") {
  110. for (var key in sub) {
  111. if (path) {
  112. _encode(sub[key], path + "%5B" + encode(key) + "%5D");
  113. } else {
  114. _encode(sub[key], encode(key));
  115. }
  116. }
  117. } else {
  118. if (!first) {
  119. str += "&";
  120. }
  121. first = false;
  122. str += path + "=" + encode(sub);
  123. }
  124. }
  125. _encode(data, "");
  126. return str;
  127. },
  128. // Do not overwrite existing attributes
  129. merge: function merge(a, b) {
  130. for (var key in b) {
  131. if (!a.hasOwnProperty(key)) {
  132. a[key] = b[key];
  133. } else if (this.isObject(b[key], 1) && this.isObject(a[key], 1)) {
  134. this.merge(a[key], b[key]);
  135. }
  136. }
  137. return a;
  138. }
  139. };
  140. /***/ }),
  141. /***/ 5:
  142. /***/ (function(module, exports, __webpack_require__) {
  143. function KEEP(_,cb){cb();}
  144. "use strict";
  145. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  146. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  147. var utils = __webpack_require__(1);
  148. var isBrowser = typeof document !== "undefined";
  149. var Fly = function () {
  150. function Fly(engine) {
  151. _classCallCheck(this, Fly);
  152. this.engine = engine || XMLHttpRequest;
  153. this.default = this; //For typeScript
  154. /**
  155. * Add lock/unlock API for interceptor.
  156. *
  157. * Once an request/response interceptor is locked, the incoming request/response
  158. * will be added to a queue before they enter the interceptor, they will not be
  159. * continued until the interceptor is unlocked.
  160. *
  161. * @param [interceptor] either is interceptors.request or interceptors.response
  162. */
  163. function wrap(interceptor) {
  164. var resolve = void 0;
  165. var reject = void 0;
  166. function _clear() {
  167. interceptor.p = resolve = reject = null;
  168. }
  169. utils.merge(interceptor, {
  170. lock: function lock() {
  171. if (!resolve) {
  172. interceptor.p = new Promise(function (_resolve, _reject) {
  173. resolve = _resolve;
  174. reject = _reject;
  175. });
  176. }
  177. },
  178. unlock: function unlock() {
  179. if (resolve) {
  180. resolve();
  181. _clear();
  182. }
  183. },
  184. clear: function clear() {
  185. if (reject) {
  186. reject("cancel");
  187. _clear();
  188. }
  189. }
  190. });
  191. }
  192. var interceptors = this.interceptors = {
  193. response: {
  194. use: function use(handler, onerror) {
  195. this.handler = handler;
  196. this.onerror = onerror;
  197. }
  198. },
  199. request: {
  200. use: function use(handler) {
  201. this.handler = handler;
  202. }
  203. }
  204. };
  205. var irq = interceptors.request;
  206. var irp = interceptors.response;
  207. wrap(irp);
  208. wrap(irq);
  209. this.config = {
  210. method: "GET",
  211. baseURL: "",
  212. headers: {},
  213. timeout: 0,
  214. params: {}, // Default Url params
  215. parseJson: true, // Convert response data to JSON object automatically.
  216. withCredentials: false
  217. };
  218. }
  219. _createClass(Fly, [{
  220. key: "request",
  221. value: function request(url, data, options) {
  222. var _this = this;
  223. var engine = new this.engine();
  224. var contentType = "Content-Type";
  225. var contentTypeLowerCase = contentType.toLowerCase();
  226. var interceptors = this.interceptors;
  227. var requestInterceptor = interceptors.request;
  228. var responseInterceptor = interceptors.response;
  229. var requestInterceptorHandler = requestInterceptor.handler;
  230. var promise = new Promise(function (resolve, reject) {
  231. if (utils.isObject(url)) {
  232. options = url;
  233. url = options.url;
  234. }
  235. options = options || {};
  236. options.headers = options.headers || {};
  237. function isPromise(p) {
  238. // some polyfill implementation of Promise may be not standard,
  239. // so, we test by duck-typing
  240. return p && p.then && p.catch;
  241. }
  242. /**
  243. * If the request/response interceptor has been locked,
  244. * the new request/response will enter a queue. otherwise, it will be performed directly.
  245. * @param [promise] if the promise exist, means the interceptor is locked.
  246. * @param [callback]
  247. */
  248. function enqueueIfLocked(promise, callback) {
  249. if (promise) {
  250. promise.then(function () {
  251. callback();
  252. });
  253. } else {
  254. callback();
  255. }
  256. }
  257. // make the http request
  258. function makeRequest(options) {
  259. data = options.body;
  260. // Normalize the request url
  261. url = utils.trim(options.url);
  262. var baseUrl = utils.trim(options.baseURL || "");
  263. if (!url && isBrowser && !baseUrl) url = location.href;
  264. if (url.indexOf("http") !== 0) {
  265. var isAbsolute = url[0] === "/";
  266. if (!baseUrl && isBrowser) {
  267. var arr = location.pathname.split("/");
  268. arr.pop();
  269. baseUrl = location.protocol + "//" + location.host + (isAbsolute ? "" : arr.join("/"));
  270. }
  271. if (baseUrl[baseUrl.length - 1] !== "/") {
  272. baseUrl += "/";
  273. }
  274. url = baseUrl + (isAbsolute ? url.substr(1) : url);
  275. if (isBrowser) {
  276. // Normalize the url which contains the ".." or ".", such as
  277. // "http://xx.com/aa/bb/../../xx" to "http://xx.com/xx" .
  278. var t = document.createElement("a");
  279. t.href = url;
  280. url = t.href;
  281. }
  282. }
  283. var responseType = utils.trim(options.responseType || "");
  284. var needQuery = ["GET", "HEAD", "DELETE", "OPTION"].indexOf(options.method) !== -1;
  285. var dataType = utils.type(data);
  286. var params = options.params || {};
  287. // merge url params when the method is "GET" (data is object)
  288. if (needQuery && dataType === "object") {
  289. params = utils.merge(data, params);
  290. }
  291. // encode params to String
  292. params = utils.formatParams(params);
  293. // save url params
  294. var _params = [];
  295. if (params) {
  296. _params.push(params);
  297. }
  298. // Add data to url params when the method is "GET" (data is String)
  299. if (needQuery && data && dataType === "string") {
  300. _params.push(data);
  301. }
  302. // make the final url
  303. if (_params.length > 0) {
  304. url += (url.indexOf("?") === -1 ? "?" : "&") + _params.join("&");
  305. }
  306. engine.open(options.method, url);
  307. // try catch for ie >=9
  308. try {
  309. engine.withCredentials = !!options.withCredentials;
  310. engine.timeout = options.timeout || 0;
  311. if (responseType !== "stream") {
  312. engine.responseType = responseType;
  313. }
  314. } catch (e) {}
  315. var customContentType = options.headers[contentType] || options.headers[contentTypeLowerCase];
  316. // default content type
  317. var _contentType = "application/x-www-form-urlencoded";
  318. // If the request data is json object, transforming it to json string,
  319. // and set request content-type to "json". In browser, the data will
  320. // be sent as RequestBody instead of FormData
  321. if (utils.trim((customContentType || "").toLowerCase()) === _contentType) {
  322. data = utils.formatParams(data);
  323. } else if (!utils.isFormData(data) && ["object", "array"].indexOf(utils.type(data)) !== -1) {
  324. _contentType = 'application/json;charset=utf-8';
  325. data = JSON.stringify(data);
  326. }
  327. //If user doesn't set content-type, set default.
  328. if (!(customContentType || needQuery)) {
  329. options.headers[contentType] = _contentType;
  330. }
  331. for (var k in options.headers) {
  332. if (k === contentType && utils.isFormData(data)) {
  333. // Delete the content-type, Let the browser set it
  334. delete options.headers[k];
  335. } else {
  336. try {
  337. // In browser environment, some header fields are readonly,
  338. // write will cause the exception .
  339. engine.setRequestHeader(k, options.headers[k]);
  340. } catch (e) {}
  341. }
  342. }
  343. function onresult(handler, data, type) {
  344. enqueueIfLocked(responseInterceptor.p, function () {
  345. if (handler) {
  346. //如果失败,添加请求信息
  347. if (type) {
  348. data.request = options;
  349. }
  350. var ret = handler.call(responseInterceptor, data, Promise);
  351. data = ret === undefined ? data : ret;
  352. }
  353. if (!isPromise(data)) {
  354. data = Promise[type === 0 ? "resolve" : "reject"](data);
  355. }
  356. data.then(function (d) {
  357. resolve(d);
  358. }).catch(function (e) {
  359. reject(e);
  360. });
  361. });
  362. }
  363. function onerror(e) {
  364. e.engine = engine;
  365. onresult(responseInterceptor.onerror, e, -1);
  366. }
  367. function Err(msg, status) {
  368. this.message = msg;
  369. this.status = status;
  370. }
  371. engine.onload = function () {
  372. try {
  373. // The xhr of IE9 has not response field
  374. var response = engine.response || engine.responseText;
  375. if (response && options.parseJson && (engine.getResponseHeader(contentType) || "").indexOf("json") !== -1
  376. // Some third engine implementation may transform the response text to json object automatically,
  377. // so we should test the type of response before transforming it
  378. && !utils.isObject(response)) {
  379. response = JSON.parse(response);
  380. }
  381. var headers = engine.responseHeaders;
  382. // In browser
  383. if (!headers) {
  384. headers = {};
  385. var items = (engine.getAllResponseHeaders() || "").split("\r\n");
  386. items.pop();
  387. items.forEach(function (e) {
  388. if (!e) return;
  389. var key = e.split(":")[0];
  390. headers[key] = engine.getResponseHeader(key);
  391. });
  392. }
  393. var status = engine.status;
  394. var statusText = engine.statusText;
  395. var _data = { data: response, headers: headers, status: status, statusText: statusText };
  396. // The _response filed of engine is set in adapter which be called in engine-wrapper.js
  397. utils.merge(_data, engine._response);
  398. if (status >= 200 && status < 300 || status === 304) {
  399. _data.engine = engine;
  400. _data.request = options;
  401. onresult(responseInterceptor.handler, _data, 0);
  402. } else {
  403. var e = new Err(statusText, status);
  404. e.response = _data;
  405. onerror(e);
  406. }
  407. } catch (e) {
  408. onerror(new Err(e.msg, engine.status));
  409. }
  410. };
  411. engine.onerror = function (e) {
  412. onerror(new Err(e.msg || "Network Error", 0));
  413. };
  414. engine.ontimeout = function () {
  415. onerror(new Err("timeout [ " + engine.timeout + "ms ]", 1));
  416. };
  417. engine._options = options;
  418. setTimeout(function () {
  419. engine.send(needQuery ? null : data);
  420. }, 0);
  421. }
  422. enqueueIfLocked(requestInterceptor.p, function () {
  423. utils.merge(options, JSON.parse(JSON.stringify(_this.config)));
  424. var headers = options.headers;
  425. headers[contentType] = headers[contentType] || headers[contentTypeLowerCase] || "";
  426. delete headers[contentTypeLowerCase];
  427. options.body = data || options.body;
  428. url = utils.trim(url || "");
  429. options.method = options.method.toUpperCase();
  430. options.url = url;
  431. var ret = options;
  432. if (requestInterceptorHandler) {
  433. ret = requestInterceptorHandler.call(requestInterceptor, options, Promise) || options;
  434. }
  435. if (!isPromise(ret)) {
  436. ret = Promise.resolve(ret);
  437. }
  438. ret.then(function (d) {
  439. //if options continue
  440. if (d === options) {
  441. makeRequest(d);
  442. } else {
  443. resolve(d);
  444. }
  445. }, function (err) {
  446. reject(err);
  447. });
  448. });
  449. });
  450. promise.engine = engine;
  451. return promise;
  452. }
  453. }, {
  454. key: "all",
  455. value: function all(promises) {
  456. return Promise.all(promises);
  457. }
  458. }, {
  459. key: "spread",
  460. value: function spread(callback) {
  461. return function (arr) {
  462. return callback.apply(null, arr);
  463. };
  464. }
  465. }]);
  466. return Fly;
  467. }();
  468. //For typeScript
  469. Fly.default = Fly;
  470. ["get", "post", "put", "patch", "head", "delete"].forEach(function (e) {
  471. Fly.prototype[e] = function (url, data, option) {
  472. return this.request(url, data, utils.merge({ method: e }, option));
  473. };
  474. });
  475. ["lock", "unlock", "clear"].forEach(function (e) {
  476. Fly.prototype[e] = function () {
  477. this.interceptors.request[e]();
  478. };
  479. });
  480. // Learn more about keep-loader: https://github.com/wendux/keep-loader
  481. KEEP("cdn||cdn-min", function () {
  482. // This code block will be removed besides the "CDN" and "cdn-min" build environment
  483. window.fly = new Fly();
  484. window.Fly = Fly;
  485. });
  486. module.exports = Fly;
  487. /***/ })
  488. /******/ });