index.esm.js 8.5 KB

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