1. /*
    2. * 支持的功能
    3. * 1.支持全局默认配置项 _ajax.defaults.xxx=xxx
    4. * 2.发送请求_ajax.get/post...
    5. * 3.每一次请求都会返回 PROMISE 实例,基于 PROMISE 设计模式进行管理
    6. * 4.支持_ajax.all
    7. */
    8. ~ function () {
    9. // 发送AJAX请求,且基于 PROMISE 进行管理
    10. class MyAjax {
    11. constructor(url, options) {
    12. this.url = url;
    13. this.options = options;
    14. return this.init();
    15. }
    16. // 发送 AJAX 请求(基于 PROMISE 来管理)
    17. init() {
    18. let {
    19. url,
    20. options: {
    21. baseURL,
    22. withCredentials,
    23. headers,
    24. transformRequest,
    25. transformResponse,
    26. validateStatus,
    27. params,
    28. data,
    29. cache,
    30. method
    31. }
    32. } = this;
    33. // 保证响应拦截器中信息的合法性
    34. !Array.isArray(transformResponse) ? transformResponse = [] : null;
    35. new Array(2).fill(null).forEach((item, index) => {
    36. typeof transformResponse[index] !== 'function' ? transformResponse[index] = null : null;
    37. });
    38. return new Promise((resolve, reject) => {
    39. let xhr = new XMLHttpRequest;
    40. // URL 的处理
    41. url = baseURL + url;
    42. if (/^(GET|DELETE|HEAD|OPTIONS)$/i.test(method)) {
    43. if (params) {
    44. let result = ``;
    45. for (let attr in params) {
    46. if (!params.hasOwnProperty(attr)) break;
    47. result += `&${attr}=${params[attr]}`;
    48. }
    49. result = result.substring(1);
    50. url += `${url.indexOf('?') === -1 ? '?' : '&'}${result}`;
    51. }
    52. if (cache === false) {
    53. url += `${url.indexOf('?') === -1 ? '?' : '&'}_=${Math.random()}`;
    54. }
    55. }
    56. xhr.open(method, url);
    57. // 结果处理
    58. xhr.onreadystatechange = () => {
    59. let resultFlag = validateStatus(xhr.status);
    60. if (!resultFlag) {
    61. reject({
    62. status: xhr.status,
    63. statusText: xhr.statusText,
    64. request: xhr
    65. });
    66. return;
    67. }
    68. if (xhr.readyState === 4) {
    69. let res_headers = {};
    70. xhr.getAllResponseHeaders().split(/\n/).forEach(item => {
    71. let [key = '', value = ''] = item.split(':');
    72. if (key.trim() === '') return;
    73. res_headers[key.trim()] = value.trim();
    74. });
    75. resolve({
    76. status: xhr.status,
    77. statusText: xhr.statusText,
    78. request: xhr,
    79. data: JSON.parse(xhr.responseText),
    80. headers: res_headers
    81. });
    82. }
    83. }
    84. // 跨域处理
    85. xhr.withCredentials = withCredentials;
    86. // 设置请求头
    87. if (headers) {
    88. for (let attr in headers) {
    89. if (!headers.hasOwnProperty(attr)) break;
    90. xhr.setRequestHeader(attr, encodeURI(headers[attr]));
    91. }
    92. }
    93. // 请求拦截器:请求主体传递信息的拦截
    94. if (/^(POST|PUT)$/i.test(method)) {
    95. typeof transformRequest === 'function' ? data = transformRequest(data) : null;
    96. } else {
    97. data = null;
    98. }
    99. xhr.send(data);
    100. }).then(...transformResponse);
    101. }
    102. }
    103. // 创建_ajax管理调用
    104. function _init(options = {}) {
    105. // 参数初始化:HEADERS 需要特殊处理(把用户 OPTIONS 中传递的 HEADERS,和 DEFAULTS 中的 HEADERS 进行合并,而不是整体替换),其余的配置项直接用 OPTIONS 中的替换 DEFAULTS 中的即可;
    106. let optionsHeaders = options.headers;
    107. _ajax.defaults.headers = Object.assign(_ajax.defaults.headers, optionsHeaders);
    108. delete options.headers;
    109. return Object.assign(_ajax.defaults, options);
    110. }
    111. function _ajax() { }
    112. _ajax.defaults = {
    113. // 全局配置项
    114. baseURL: '',
    115. withCredentials: true,
    116. headers: {
    117. 'Content-Type': 'application/x-www-form-urlencoded'
    118. },
    119. transformRequest: function (data) {
    120. if (!data) return data;
    121. let result = ``;
    122. for (let attr in data) {
    123. if (!data.hasOwnProperty(attr)) break;
    124. result += `&${attr}=${data[attr]}`;
    125. }
    126. return result.substring(1);
    127. },
    128. transformResponse: [function onFulfilled(response) {
    129. return response.data;
    130. }, function onRejected(reason) {
    131. return Promise.reject(reason);
    132. }],
    133. validateStatus: function (status) {
    134. return /^(2|3)\d{2}$/.test(status);
    135. },
    136. // 请求配置项
    137. params: {},
    138. data: {},
    139. cache: true
    140. };
    141. _ajax.all = function all(promiseArr = []) {
    142. return Promise.all(promiseArr);
    143. };
    144. ["get", "delete", "head", "options"].forEach(item => {
    145. _ajax[item] = function (url, options = {}) {
    146. options.method = item;
    147. return new MyAjax(url, _init(options));
    148. };
    149. });
    150. ["post", "put"].forEach(item => {
    151. _ajax[item] = function (url, data = {}, options = {}) {
    152. // 把 DATA 也放到配置项目
    153. options.data = data;
    154. options.method = item;
    155. return new MyAjax(url, _init(options));
    156. };
    157. });
    158. window._ajax = _ajax;
    159. }();