request.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import fetch from 'dva/fetch';
  2. import { message } from 'antd';
  3. import { routerRedux } from 'dva/router';
  4. import store from '../index';
  5. const codeMessage = {
  6. 200: '服务器成功返回请求的数据。',
  7. 201: '新建或修改数据成功。',
  8. 202: '一个请求已经进入后台排队(异步任务)。',
  9. 204: '删除数据成功。',
  10. 400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
  11. 401: '用户没有权限(令牌、用户名、密码错误)。',
  12. 403: '用户得到授权,但是访问是被禁止的。',
  13. 404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
  14. 406: '请求的格式不可得。',
  15. 410: '请求的资源被永久删除,且不会再得到的。',
  16. 422: '当创建一个对象时,发生一个验证错误。',
  17. 500: '服务器发生错误,请检查服务器。',
  18. 502: '网关错误。',
  19. 503: '服务不可用,服务器暂时过载或维护。',
  20. 504: '网关超时。',
  21. };
  22. function checkHttpStatus(response) {
  23. if (response.status >= 200 && response.status < 300) {
  24. return response;
  25. }
  26. const errortext = codeMessage[response.status] || response.statusText;
  27. message.error(`请求错误 ${response.url}: ${errortext}`);
  28. const error = new Error(errortext);
  29. error.name = response.status;
  30. error.response = response;
  31. throw error;
  32. }
  33. function checkContentStatus(data) {
  34. if (!data.success) {
  35. const errortext = codeMessage[data.code] || data.message;
  36. if (data.code < 10002 || data.code >= 10005) {
  37. message.error(errortext);
  38. }
  39. const error = new Error(errortext);
  40. error.name = data.code;
  41. error.response = data;
  42. throw error;
  43. }
  44. return data;
  45. }
  46. /**
  47. * Requests a URL, returning a promise.
  48. *
  49. * @param {string} url The URL we want to request
  50. * @param {object} [options] The options we want to pass to "fetch"
  51. * @return {object} An object containing either "data" or "err"
  52. */
  53. export default function request(url, options) {
  54. const defaultOptions = {
  55. credentials: 'include',
  56. };
  57. const newOptions = { ...defaultOptions, ...options };
  58. if (newOptions.method === 'POST' || newOptions.method === 'PUT' || newOptions.method === 'DELETE') {
  59. if (!(newOptions.body instanceof FormData)) {
  60. newOptions.headers = {
  61. Accept: 'application/json',
  62. 'Content-Type': 'application/json; charset=utf-8',
  63. ...newOptions.headers,
  64. };
  65. // newOptions.body is Object
  66. if (newOptions.body instanceof Object) {
  67. newOptions.body = JSON.stringify(newOptions.body);
  68. }
  69. } else {
  70. newOptions.headers = {
  71. Accept: 'application/json',
  72. 'Content-Type': 'multipart/form-data',
  73. ...newOptions.headers,
  74. };
  75. }
  76. }
  77. return fetch(url, newOptions)
  78. .then(checkHttpStatus)
  79. .then((response) => {
  80. if (response.status === 204) {
  81. return response.text();
  82. }
  83. return response.json();
  84. })
  85. .then(checkContentStatus)
  86. .catch((e) => {
  87. const { dispatch } = store;
  88. const status = e.name;
  89. if (status === 401) {
  90. dispatch({
  91. type: 'login/logout',
  92. });
  93. }
  94. if (status === 403) {
  95. dispatch(routerRedux.push('/exception/403'));
  96. }
  97. if (status <= 504 && status >= 500) {
  98. dispatch(routerRedux.push('/exception/500'));
  99. }
  100. if (status >= 404 && status < 422) {
  101. dispatch(routerRedux.push('/exception/404'));
  102. }
  103. if (status >= 10002 && status < 10005) {
  104. dispatch(routerRedux.push('/user/login'));
  105. }
  106. return e.response;
  107. });
  108. }