request.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // src/utils/request.js
  2. import axios from 'axios'
  3. import qs from 'qs'
  4. import { debounce } from './debounce'
  5. import { Message } from 'element-ui';
  6. const contentTypes = {
  7. json: 'application/json; charset=utf-8',
  8. urlencoded: 'application/x-www-form-urlencoded; charset=utf-8',
  9. multipart: 'multipart/form-data',
  10. }
  11. function toastMsg() {
  12. Object.keys(errorMsgObj).map((item) => {
  13. Message.error(item)
  14. delete errorMsgObj[item]
  15. })
  16. }
  17. let errorMsgObj = {}
  18. const defaultOptions = {
  19. withCredentials: true, // 允许把cookie传递到后台
  20. headers: {
  21. Accept: 'application/json',
  22. 'Content-Type': contentTypes.json
  23. },
  24. timeout: 60000,
  25. }
  26. export const callApi = ({
  27. url,
  28. data = {},
  29. method = 'get',
  30. options = {},
  31. contentType = 'json', // json || urlencoded || multipart
  32. prefixUrl = 'api',
  33. responseType
  34. }) => {
  35. if (!url) {
  36. const error = new Error('请传入url')
  37. return Promise.reject(error)
  38. }
  39. const fullUrl = `/${prefixUrl}/${url}`
  40. const newOptions = {
  41. ...defaultOptions,
  42. ...options,
  43. headers: {
  44. 'Content-Type':
  45. (options.headers && options.headers['Content-Type']) ||
  46. contentTypes[contentType],
  47. },
  48. method,
  49. }
  50. if (method === 'get') {
  51. newOptions.params = data
  52. }
  53. if (method !== 'get' && method !== 'head') {
  54. newOptions.data = data
  55. if (data instanceof FormData) {
  56. newOptions.headers = {
  57. 'x-requested-with': 'XMLHttpRequest',
  58. 'cache-control': 'no-cache',
  59. }
  60. } else if (newOptions.headers['Content-Type'] === contentTypes.urlencoded) {
  61. newOptions.data = qs.stringify(data)
  62. } else {
  63. Object.keys(data).forEach((item) => {
  64. if (
  65. data[item] === null ||
  66. data[item] === undefined ||
  67. data[item] === ''
  68. ) {
  69. delete data[item]
  70. }
  71. })
  72. // 没有必要,因为axios会将JavaScript对象序列化为JSON
  73. // newOptions.data = JSON.stringify(data);
  74. }
  75. }
  76. axios.interceptors.request.use((request) => {
  77. // 移除起始部分 / 所有请求url走相对路径
  78. request.url = request.url.replace(/^\//, '')
  79. // console.log('prefixUrl', prefixUrl);
  80. return request
  81. })
  82. return axios({
  83. url: fullUrl,
  84. ...newOptions,
  85. }).then((response) => {
  86. const { data } = response
  87. if (data.code == 'xxx') {
  88. // 与服务端约定
  89. // 登录校验失败
  90. } else if (data.code == 'xxx') {
  91. // 与服务端约定
  92. // 无权限
  93. router.replace({ path: '/403' })
  94. } else if (data.code == '200') {
  95. // 与服务端约定
  96. return Promise.resolve(data)
  97. } else {
  98. console.log('4444');
  99. const { message } = data
  100. if (!errorMsgObj[message]) {
  101. errorMsgObj[message] = message
  102. }
  103. setTimeout(debounce(toastMsg, 1000, true), 1000)
  104. return Promise.reject(data)
  105. }
  106. }).catch((error) => {
  107. console.log('error', error);
  108. if (error.response) {
  109. const { data } = error.response
  110. const resCode = data.status
  111. const resMsg = data.message || error.message || '服务异常'
  112. // if (resCode === 401) { // 与服务端约定
  113. // // 登录校验失败
  114. // } else if (data.code === 403) { // 与服务端约定
  115. // // 无权限
  116. // router.replace({ path: '/403' })
  117. // }
  118. if (!errorMsgObj[resMsg]) {
  119. errorMsgObj[resMsg] = resMsg
  120. }
  121. setTimeout(debounce(toastMsg, 1000, true), 1000)
  122. const err = { code: resCode, respMsg: resMsg }
  123. return Promise.reject(err)
  124. } else {
  125. const err = { type: 'canceled', respMsg: '数据请求超时' }
  126. return Promise.reject(err)
  127. }
  128. })
  129. }