request.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. import fetch from 'dva/fetch';
  2. import { message, notification } from 'antd';
  3. import router from 'umi/router';
  4. import hash from 'hash.js';
  5. import { isAntdPro, getToken, GetTokenFromUrl } from './utils';
  6. // var apiUrl = "http://oraysmart.com:8888"
  7. // var apiUrl = "http://120.55.44.4:8900"
  8. const checkStatus = response => {
  9. if (response.status >= 200 && response.status < 300) {
  10. return response;
  11. }
  12. // if (
  13. // response.status == 400 ||
  14. // response.status == 401 ||
  15. // response.status == 601 ||
  16. // response.status == 602
  17. // ) {
  18. // response
  19. // .json()
  20. // .then(body => {
  21. // notification.error({
  22. // message: '错误',
  23. // description: `${body.msg}-${body.data}: ${response.url}`,
  24. // });
  25. // })
  26. // .catch(err => {
  27. // notification.error({
  28. // message: '错误',
  29. // description: 'token失效,请重新登录',
  30. // });
  31. // });
  32. // return response;
  33. // }
  34. // if (response.status === 600) {
  35. // return response;
  36. // }
  37. const error = new Error(response.data);
  38. error.name = response.status;
  39. error.response = response;
  40. console.error(error)
  41. // throw error;
  42. return Promise.reject()
  43. };
  44. const cachedSave = response => {
  45. if (response.status === 600) return response;
  46. /**
  47. * Clone a response data and store it in sessionStorage
  48. * Does not support data other than json, Cache only json
  49. */
  50. const contentType = response.headers.get('Content-Type');
  51. if (contentType && contentType.match(/application\/json/i)) {
  52. // All data is saved as text
  53. response
  54. .clone()
  55. .text()
  56. .then(() => {
  57. // sessionStorage.setItem(hashcode, content);
  58. // sessionStorage.setItem(`${hashcode}:timestamp`, Date.now());
  59. });
  60. }
  61. return response;
  62. };
  63. /**
  64. * Requests a URL, returning a promise.
  65. *
  66. * @param {string} url The URL we want to request
  67. * @param {object} [option] The options we want to pass to "fetch"
  68. * @return {object} An object containing either "data" or "err"
  69. */
  70. export default function request(url, option, jwt) {
  71. const number = new Date().getTime();
  72. // console.log(API_HOST);
  73. const time = url.indexOf('?') > -1 ? `&time=${number}` : `?time=${number}`;
  74. if (url.indexOf('http://') == -1 && url.indexOf('https://') == -1) {
  75. if (url.indexOf('/api/v') === -1) {
  76. url = `/api/v1${url}${time}`;
  77. }
  78. // API_HOST在config/config.js的define中配置
  79. // url = API_HOST + url
  80. }
  81. let token = getToken();
  82. if (!token) {
  83. token = GetTokenFromUrl();
  84. }
  85. const options = {
  86. expirys: isAntdPro(),
  87. ...option,
  88. };
  89. /**
  90. * Produce fingerprints based on url and parameters
  91. * Maybe url has the same parameters
  92. */
  93. const fingerprint = url + (options.body ? JSON.stringify(options.body) : '');
  94. const hashcode = hash
  95. .sha256()
  96. .update(fingerprint)
  97. .digest('hex');
  98. const defaultOptions = {
  99. credentials: 'include',
  100. };
  101. const newOptions = { ...defaultOptions, ...options };
  102. newOptions.headers = {
  103. ...newOptions.headers,
  104. 'JWT-TOKEN': jwt ? jwt : `${token}`,
  105. };
  106. if (
  107. newOptions.method === 'POST' ||
  108. newOptions.method === 'PUT' ||
  109. newOptions.method === 'DELETE'
  110. ) {
  111. if (!(newOptions.body instanceof FormData)) {
  112. newOptions.headers = {
  113. Accept: 'application/json',
  114. 'Content-Type': 'application/json;charset=utf-8',
  115. ...newOptions.headers,
  116. };
  117. newOptions.body = JSON.stringify(newOptions.body);
  118. } else {
  119. // newOptions.body is FormData
  120. newOptions.headers = {
  121. Accept: 'application/json',
  122. ...newOptions.headers,
  123. };
  124. }
  125. }
  126. const expirys = options.expirys && 60;
  127. // options.expirys !== false, return the cache,
  128. if (options.expirys !== false) {
  129. const cached = sessionStorage.getItem(hashcode);
  130. const whenCached = sessionStorage.getItem(`${hashcode}:timestamp`);
  131. if (cached !== null && whenCached !== null) {
  132. const age = (Date.now() - whenCached) / 1000;
  133. if (age < expirys) {
  134. const response = new Response(new Blob([cached]));
  135. return response.json();
  136. }
  137. sessionStorage.removeItem(hashcode);
  138. sessionStorage.removeItem(`${hashcode}:timestamp`);
  139. }
  140. }
  141. return fetch(url, newOptions)
  142. .then(checkStatus)
  143. .then(response => cachedSave(response, hashcode))
  144. .then(response => {
  145. // DELETE and 204 do not return data by default
  146. // using .json will report an error.
  147. if (response.status === 204) {
  148. return response.text();
  149. }
  150. // if (response.status === 600) {
  151. // return response;
  152. // } else {
  153. return response.json();
  154. // }
  155. })
  156. .then(response => {
  157. let code = response.code;
  158. if (typeof response === 'string') {
  159. return response;
  160. } else if (code !== 200) {
  161. if (code === 401 || code === 601 || code === 602) {
  162. // 用户token出错,重定向
  163. notification.error({
  164. message: '错误',
  165. description: 'token失效,请重新登录',
  166. });
  167. router.push('/login');
  168. } else {
  169. message.error(response.msg);
  170. }
  171. return false;
  172. } else {
  173. return response;
  174. }
  175. })
  176. .catch(e => {
  177. const status = e?.name;
  178. // environment should not be used
  179. if (status === 401 || status === 601 || status === 602 || status === 400) {
  180. // 用户token出错,重定向
  181. notification.error({
  182. message: '错误',
  183. description: 'token失效,请重新登录',
  184. });
  185. router.push('/login');
  186. return;
  187. }
  188. // if (status <= 504 && status > 500 && status !== 600) {
  189. // router.push('/exception/500');
  190. // throw e;
  191. // }
  192. // if (status >= 404 && status < 422) {
  193. // router.push('/exception/404');
  194. // throw e;
  195. // }
  196. // if (status === 600) {
  197. // throw e;
  198. // }
  199. notification.error({
  200. message: '错误',
  201. description: `HTTP请求错误,错误码:${status};接口地址${url}`,
  202. });
  203. throw e;
  204. });
  205. }