index.aio.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*!
  2. * axios-miniprogram-adapter 0.3.1 (https://github.com/bigMeow/axios-miniprogram-adapter)
  3. * API https://github.com/bigMeow/axios-miniprogram-adapter/blob/master/doc/api.md
  4. * Copyright 2018-2020 bigMeow. All Rights Reserved
  5. * Licensed under MIT (https://github.com/bigMeow/axios-miniprogram-adapter/blob/master/LICENSE)
  6. */
  7. (function (global, factory) {
  8. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('axios/lib/utils'), require('axios/lib/core/settle'), require('axios/lib/helpers/buildURL'), require('axios/lib/core/buildFullPath'), require('axios/lib/core/createError')) :
  9. typeof define === 'function' && define.amd ? define(['axios/lib/utils', 'axios/lib/core/settle', 'axios/lib/helpers/buildURL', 'axios/lib/core/buildFullPath', 'axios/lib/core/createError'], factory) :
  10. (global = global || self, global['axios-miniprogram-adapter'] = factory(global.utils, global.settle, global.buildURL, global.buildFullPath, global.createError));
  11. }(this, (function (utils, settle, buildURL, buildFullPath, createError) { 'use strict';
  12. utils = utils && Object.prototype.hasOwnProperty.call(utils, 'default') ? utils['default'] : utils;
  13. settle = settle && Object.prototype.hasOwnProperty.call(settle, 'default') ? settle['default'] : settle;
  14. buildURL = buildURL && Object.prototype.hasOwnProperty.call(buildURL, 'default') ? buildURL['default'] : buildURL;
  15. buildFullPath = buildFullPath && Object.prototype.hasOwnProperty.call(buildFullPath, 'default') ? buildFullPath['default'] : buildFullPath;
  16. createError = createError && Object.prototype.hasOwnProperty.call(createError, 'default') ? createError['default'] : createError;
  17. var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
  18. // encoder
  19. function encoder(input) {
  20. var str = String(input);
  21. // initialize result and counter
  22. var block;
  23. var charCode;
  24. var idx = 0;
  25. var map = chars;
  26. var output = '';
  27. for (;
  28. // if the next str index does not exist:
  29. // change the mapping table to "="
  30. // check if d has no fractional digits
  31. str.charAt(idx | 0) || (map = '=', idx % 1);
  32. // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8
  33. output += map.charAt(63 & block >> 8 - idx % 1 * 8)) {
  34. charCode = str.charCodeAt(idx += 3 / 4);
  35. if (charCode > 0xFF) {
  36. throw new Error("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");
  37. }
  38. block = block << 8 | charCode;
  39. }
  40. return output;
  41. }
  42. var platFormName = 'wechat';
  43. /**
  44. * 获取各个平台的请求函数
  45. */
  46. function getRequest() {
  47. switch (true) {
  48. case typeof wx === 'object':
  49. platFormName = 'wechat';
  50. return wx.request.bind(wx);
  51. case typeof swan === 'object':
  52. platFormName = 'baidu';
  53. return swan.request.bind(swan);
  54. case typeof my === 'object':
  55. /**
  56. * remark:
  57. * 支付宝客户端已不再维护 my.httpRequest,建议使用 my.request。另外,钉钉客户端尚不支持 my.request。若在钉钉客户端开发小程序,则需要使用 my.httpRequest。
  58. * my.httpRequest的请求头默认值为{'content-type': 'application/x-www-form-urlencoded'}。
  59. * my.request的请求头默认值为{'content-type': 'application/json'}。
  60. * TODO: 区分支付宝和钉钉环境
  61. * 还有个 dd.httpRequest WFK!!! https://ding-doc.dingtalk.com/doc#/dev/httprequest
  62. */
  63. platFormName = 'alipay';
  64. return (my.request || my.httpRequest).bind(my);
  65. default:
  66. return wx.request.bind(wx);
  67. }
  68. }
  69. /**
  70. * 处理各平台返回的响应数据,抹平差异
  71. * @param mpResponse
  72. * @param config axios处理过的请求配置对象
  73. * @param request 小程序的调用发起请求时,传递给小程序api的实际配置
  74. */
  75. function transformResponse(mpResponse, config, mpRequestOption) {
  76. var headers = mpResponse.header || mpResponse.headers;
  77. var status = mpResponse.statusCode || mpResponse.status;
  78. var statusText = '';
  79. if (status === 200) {
  80. statusText = 'OK';
  81. }
  82. else if (status === 400) {
  83. statusText = 'Bad Request';
  84. }
  85. var response = {
  86. data: mpResponse.data,
  87. status: status,
  88. statusText: statusText,
  89. headers: headers,
  90. config: config,
  91. request: mpRequestOption
  92. };
  93. return response;
  94. }
  95. /**
  96. * 处理各平台返回的错误信息,抹平差异
  97. * @param error 小程序api返回的错误对象
  98. * @param reject 上层的promise reject 函数
  99. * @param config
  100. */
  101. function transformError(error, reject, config) {
  102. switch (platFormName) {
  103. case 'wechat':
  104. if (error.errMsg.indexOf('request:fail abort') !== -1) {
  105. // Handle request cancellation (as opposed to a manual cancellation)
  106. reject(createError('Request aborted', config, 'ECONNABORTED', ''));
  107. }
  108. else if (error.errMsg.indexOf('timeout') !== -1) {
  109. // timeout
  110. reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED', ''));
  111. }
  112. else {
  113. // NetWordError
  114. reject(createError('Network Error', config, null, ''));
  115. }
  116. break;
  117. case 'alipay':
  118. // https://docs.alipay.com/mini/api/network
  119. if ([14, 19].includes(error.error)) {
  120. reject(createError('Request aborted', config, 'ECONNABORTED', ''));
  121. }
  122. else if ([13].includes(error.error)) {
  123. // timeout
  124. reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED', ''));
  125. }
  126. else {
  127. // NetWordError
  128. reject(createError('Network Error', config, null, ''));
  129. }
  130. break;
  131. case 'baidu':
  132. // TODO error.errCode
  133. reject(createError('Network Error', config, null, ''));
  134. break;
  135. }
  136. }
  137. /**
  138. * 将axios的请求配置,转换成各个平台都支持的请求config
  139. * @param config
  140. */
  141. function transformConfig(config) {
  142. if (platFormName === 'alipay') {
  143. config.headers = config.header;
  144. delete config.header;
  145. }
  146. return config;
  147. }
  148. var warn = console.warn;
  149. var isJSONstr = function (str) {
  150. try {
  151. return typeof str === 'string' && str.length && (str = JSON.parse(str)) && Object.prototype.toString.call(str) === '[object Object]';
  152. }
  153. catch (error) {
  154. return false;
  155. }
  156. };
  157. function mpAdapter(config) {
  158. var request = getRequest();
  159. return new Promise(function (resolve, reject) {
  160. var requestTask;
  161. var requestData = config.data;
  162. var requestHeaders = config.headers;
  163. // baidu miniprogram only support upperCase
  164. var requestMethod = (config.method && config.method.toUpperCase()) || 'GET';
  165. // miniprogram network request config
  166. var mpRequestOption = {
  167. method: requestMethod,
  168. url: buildURL(buildFullPath(config.baseURL, config.url), config.params, config.paramsSerializer),
  169. // Listen for success
  170. success: function (mpResponse) {
  171. var response = transformResponse(mpResponse, config, mpRequestOption);
  172. settle(resolve, reject, response);
  173. },
  174. // Handle request Exception
  175. fail: function (error) {
  176. transformError(error, reject, config);
  177. },
  178. complete: function () {
  179. requestTask = undefined;
  180. }
  181. };
  182. // HTTP basic authentication
  183. if (config.auth) {
  184. var _a = [config.auth.username || '', config.auth.password || ''], username = _a[0], password = _a[1];
  185. requestHeaders.Authorization = 'Basic ' + encoder(username + ':' + password);
  186. }
  187. // Set the request timeout
  188. if (config.timeout !== 0) {
  189. warn('The "timeout" option is not supported by miniprogram. For more information about usage see "https://developers.weixin.qq.com/miniprogram/dev/framework/config.html#全局配置"');
  190. }
  191. // Add headers to the request
  192. utils.forEach(requestHeaders, function setRequestHeader(val, key) {
  193. var _header = key.toLowerCase();
  194. if ((typeof requestData === 'undefined' && _header === 'content-type') || _header === 'referer') {
  195. // Remove Content-Type if data is undefined
  196. // And the miniprogram document said that '设置请求的 header,header 中不能设置 Referer'
  197. delete requestHeaders[key];
  198. }
  199. });
  200. mpRequestOption.header = requestHeaders;
  201. // Add responseType to request if needed
  202. if (config.responseType) {
  203. mpRequestOption.responseType = config.responseType;
  204. }
  205. if (config.cancelToken) {
  206. // Handle cancellation
  207. config.cancelToken.promise.then(function onCanceled(cancel) {
  208. if (!requestTask) {
  209. return;
  210. }
  211. requestTask.abort();
  212. reject(cancel);
  213. // Clean up request
  214. requestTask = undefined;
  215. });
  216. }
  217. // Converting JSON strings to objects is handed over to the MiniPrograme
  218. if (isJSONstr(requestData)) {
  219. requestData = JSON.parse(requestData);
  220. }
  221. if (requestData !== undefined) {
  222. mpRequestOption.data = requestData;
  223. }
  224. requestTask = request(transformConfig(mpRequestOption));
  225. });
  226. }
  227. return mpAdapter;
  228. })));