ajax.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. const http = {
  2. /**
  3. * js封装ajax请求
  4. * >>使用new XMLHttpRequest 创建请求对象,所以不考虑低端IE浏览器(IE6及以下不支持XMLHttpRequest)
  5. * >>使用es6语法,如果需要在正式环境使用,则可以用babel转换为es5语法 https://babeljs.cn/docs/setup/#installation
  6. * @param settings 请求参数模仿jQuery ajax
  7. * 调用该方法,data参数需要和请求头Content-Type对应
  8. * Content-Type data 描述
  9. * application/x-www-form-urlencoded 'name=哈哈&age=12'或{name:'哈哈',age:12} 查询字符串,用&分割
  10. * application/json name=哈哈&age=12' json字符串
  11. * multipart/form-data new FormData() FormData对象,当为FormData类型,不要手动设置Content-Type
  12. * 注意:请求参数如果包含日期类型.是否能请求成功需要后台接口配合
  13. */
  14. ajax: (settings = {}) => {
  15. // 初始化请求参数
  16. let _s = Object.assign({
  17. url: '', // string
  18. type: 'GET', // string 'GET' 'POST' 'DELETE'
  19. dataType: 'json', // string 期望的返回数据类型:'json' 'text' 'document' ...
  20. async: true, // boolean true:异步请求 false:同步请求 required
  21. data: null, // any 请求参数,data需要和请求头Content-Type对应
  22. headers: { 'Content-Type': "application/json" }, // object 请求头
  23. timeout: 1000, // string 超时时间:0表示不设置超时
  24. beforeSend: (xhr) => {
  25. },
  26. success: (result, status, xhr) => {
  27. },
  28. error: (xhr, status, error) => {
  29. },
  30. complete: (xhr, status) => {
  31. }
  32. }, settings);
  33. // 参数验证
  34. if (!_s.url || !_s.type || !_s.dataType || !_s.async) {
  35. alert('参数有误');
  36. return;
  37. }
  38. // 创建XMLHttpRequest请求对象
  39. let xhr = new XMLHttpRequest();
  40. // 请求开始回调函数
  41. xhr.addEventListener('loadstart', e => {
  42. _s.beforeSend(xhr);
  43. });
  44. // 请求成功回调函数
  45. xhr.addEventListener('load', e => {
  46. const status = xhr.status;
  47. if ((status >= 200 && status < 300) || status === 304) {
  48. let result;
  49. if (xhr.responseType === 'text') {
  50. result = xhr.responseText;
  51. } else if (xhr.responseType === 'document') {
  52. result = xhr.responseXML;
  53. } else {
  54. result = xhr.response;
  55. }
  56. // 注意:状态码200表示请求发送/接受成功,不表示业务处理成功
  57. _s.success(result, status, xhr);
  58. } else {
  59. _s.error(xhr, status, e);
  60. }
  61. });
  62. // 请求结束
  63. xhr.addEventListener('loadend', e => {
  64. _s.complete(xhr, xhr.status);
  65. });
  66. // 请求出错
  67. xhr.addEventListener('error', e => {
  68. _s.error(xhr, xhr.status, e);
  69. });
  70. // 请求超时
  71. xhr.addEventListener('timeout', e => {
  72. _s.error(xhr, 408, e);
  73. });
  74. let useUrlParam = false;
  75. let sType = _s.type.toUpperCase();
  76. // 如果是"简单"请求,则把data参数组装在url上
  77. if (sType === 'GET' || sType === 'DELETE') {
  78. useUrlParam = true;
  79. _s.url += http.getUrlParam(_s.url, _s.data);
  80. }
  81. // 初始化请求
  82. xhr.open(_s.type, _s.url, _s.async);
  83. // 设置期望的返回数据类型
  84. xhr.responseType = _s.dataType;
  85. // 设置请求头
  86. for (const key of Object.keys(_s.headers)) {
  87. xhr.setRequestHeader(key, _s.headers[key]);
  88. }
  89. // 设置超时时间
  90. if (_s.async && _s.timeout) {
  91. xhr.timeout = _s.timeout;
  92. }
  93. // 发送请求.如果是简单请求,请求参数应为null.否则,请求参数类型需要和请求头Content-Type对应
  94. xhr.send(useUrlParam ? null : http.getQueryData(_s.data));
  95. },
  96. // 把参数data转为url查询参数
  97. getUrlParam: (url, data) => {
  98. if (!data) {
  99. return '';
  100. }
  101. let paramsStr = data instanceof Object ? http.getQueryString(data) : data;
  102. return (url.indexOf('?') !== -1) ? paramsStr : '?' + paramsStr;
  103. },
  104. // 获取ajax请求参数
  105. getQueryData: (data) => {
  106. if (!data) {
  107. return null;
  108. }
  109. if (typeof data === 'string') {
  110. return data;
  111. }
  112. if (data instanceof FormData) {
  113. return data;
  114. }
  115. return http.getQueryString(data);
  116. },
  117. // 把对象转为查询字符串
  118. getQueryString: (data) => {
  119. let paramsArr = [];
  120. if (data instanceof Object) {
  121. Object.keys(data).forEach(key => {
  122. let val = data[key];
  123. // todo 参数Date类型需要根据后台api酌情处理
  124. if (val instanceof Date) {
  125. // val = dateFormat(val, 'yyyy-MM-dd hh:mm:ss');
  126. }
  127. paramsArr.push(encodeURIComponent(key) + '=' + encodeURIComponent(val));
  128. });
  129. }
  130. return paramsArr.join('&');
  131. }
  132. }