request.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. import axios from 'axios';
  2. import qs from 'qs';
  3. import { Message } from 'element-ui';
  4. import store from '@/store';
  5. import { getToken, setToken } from '@/utils/auth';
  6. /**
  7. * 设置全局参数
  8. */
  9. axios.defaults.baseURL = process.env.VUE_APP_BASE_API;
  10. // axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
  11. // axios.defaults.withCredentials = true
  12. axios.defaults.timeout = process.env.VUE_APP_API_TIMEOUT;
  13. // create an axios instance
  14. const service = axios.create({
  15. baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  16. // withCredentials: true, // send cookies when cross-domain requests
  17. timeout: 5000 // request timeout
  18. });
  19. // request interceptor
  20. axios.interceptors.request.use(
  21. config => {
  22. // do something before request is sent
  23. if (store.getters.token) {
  24. // let each request carry token
  25. // ['X-Token'] is a custom headers key
  26. // please modify it according to the actual situation
  27. config.headers['token'] = getToken();
  28. }
  29. return config;
  30. },
  31. error => {
  32. // do something with request error
  33. console.log(error); // for debug
  34. return Promise.reject(error);
  35. }
  36. );
  37. // response interceptor
  38. axios.interceptors.response.use(
  39. /**
  40. * If you want to get http information such as headers or status
  41. * Please return response => response
  42. */
  43. response => {
  44. const res = response.data;
  45. if (res.code === 401) {
  46. setToken();
  47. // 045 登录态失效,重定向到登录页 更改地址
  48. location.replace(`https://youxiangle.cn/yxl-admin/#/login`);
  49. Message({
  50. message: 'Token失效,请重新登陆',
  51. type: 'error',
  52. duration: 5 * 1000
  53. });
  54. return Promise.reject(new Error(''));
  55. }
  56. return res;
  57. },
  58. error => {
  59. console.log('错误 response', error);
  60. return Promise.reject(error);
  61. }
  62. );
  63. // 预处理配置文件
  64. const pretreatConfig = _config => {
  65. if (_config && 'dataType' in _config) {
  66. if (_config.dataType === 'json') {
  67. Object.assign(_config, {
  68. headers: {
  69. 'Content-Type': 'application/json;charset=UTF-8'
  70. }
  71. });
  72. } else if (_config.dataType === 'formdata') {
  73. Object.assign(_config, {
  74. headers: {
  75. 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
  76. }
  77. });
  78. }
  79. }
  80. if (
  81. process.env.NODE_ENV !== 'production' &&
  82. _config &&
  83. 'mock' in _config &&
  84. _config.mock
  85. ) {
  86. Object.assign(_config, {
  87. baseURL: process.env.VUE_APP_BASE_API_MOCK
  88. });
  89. }
  90. return _config;
  91. };
  92. /**
  93. * 处理response
  94. * @param {axios请求结果} fetchResult
  95. */
  96. const formatResponse = fetchResult =>
  97. fetchResult
  98. .then(response => formatStatus(response))
  99. .then(res => formatCode(res), handleNetworkError);
  100. /**
  101. * 格式化status
  102. */
  103. const formatStatus = response => {
  104. // 如果http状态码正常,则直接返回数据
  105. if (response && response.code === 200) {
  106. response.success = true;
  107. return response;
  108. // 如果不需要除了data之外的数据,可以直接 return response.data
  109. }
  110. // console.warn('---------------2-----------------')
  111. // console.warn(response)
  112. let txt = '网络异常';
  113. if (!response) {
  114. txt = '通信错误';
  115. } else if (response.code === 500) {
  116. txt = response.msg || '服务器错误';
  117. // } else if (response.code === 401) {
  118. // txt = '身份验证失败'
  119. }
  120. Message({
  121. message: txt || 'Error',
  122. type: 'error',
  123. duration: 5 * 1000
  124. });
  125. // 异常状态下,把错误信息返回去
  126. return {
  127. code: -404,
  128. msg: txt,
  129. request: response.request || {}
  130. };
  131. };
  132. /**
  133. * 格式化code
  134. */
  135. const formatCode = ({ code, data, msg }) => {
  136. // 如果code异常(这里已经包括网络错误,服务器错误,后端抛出的错误),可以弹出一个错误提示,告诉用户
  137. if (code === -404) {
  138. return {
  139. code: code,
  140. success: false,
  141. msg,
  142. data: {}
  143. };
  144. }
  145. // // api内置错误类型
  146. // if (data && !data.success) {
  147. // let msg = data.msg
  148. // if (data.code === 500) {
  149. // msg = '内部服务器错误'
  150. // }
  151. // return {
  152. // success: false,
  153. // msg,
  154. // code: data.code,
  155. // errorObj: data.error,
  156. // data: {}
  157. // }
  158. // }
  159. return {
  160. success: code === 200,
  161. msg,
  162. code,
  163. data
  164. };
  165. };
  166. // 处理网络通信错误
  167. const handleNetworkError = error => {
  168. if (error) {
  169. if (error.response && error.response.status === 500) {
  170. return {
  171. code: 500,
  172. success: false,
  173. msg: '通信错误',
  174. data: {}
  175. };
  176. } else if (error.response && error.response.status === 401) {
  177. store.dispatch('user/resetToken');
  178. setToken();
  179. // location.replace(`http://wxhd.lifespaceprobiotics.cn/code/admin/#/login`);
  180. }
  181. if (error.message.includes('timeout')) {
  182. return {
  183. code: 1,
  184. success: false,
  185. msg: '通信超时',
  186. data: {}
  187. };
  188. // } if (error.msg.includes('404')) {
  189. // return {
  190. // code: 1,
  191. // success: false,
  192. // msg: '通信失败',
  193. // data: {}
  194. // }
  195. }
  196. }
  197. return {
  198. code: -1,
  199. success: false,
  200. msg: '',
  201. data: {}
  202. };
  203. };
  204. /* 暂时不需要下载 要调整 */
  205. // const formatDownload = (fetchResult, name = '压缩文件') => fetchResult
  206. // .then(response => {
  207. // const filename = `${name}.zip`
  208. // const blob = response
  209. // if (typeof window.navigator.msSaveBlob !== 'undefined') {
  210. // // IE workaround for "HTML7007: One or more blob URLs were
  211. // // revoked by closing the blob for which they were created.
  212. // // These URLs will no longer resolve as the data backing
  213. // // the URL has been freed."
  214. // window.navigator.msSaveBlob(blob, filename)
  215. // } else {
  216. // const blobURL = window.URL.createObjectURL(blob)
  217. // const tempLink = document.createElement('a')
  218. // tempLink.style.display = 'none'
  219. // tempLink.href = blobURL
  220. // tempLink.setAttribute('download', filename)
  221. // // Safari thinks _blank anchor are pop ups. We only want to set _blank
  222. // // target if the browser does not support the HTML5 download attribute.
  223. // // This allows you to download files in desktop safari if pop up blocking
  224. // // is enabled.
  225. // if (typeof tempLink.download === 'undefined') {
  226. // tempLink.setAttribute('target', '_blank')
  227. // }
  228. // document.body.appendChild(tempLink)
  229. // tempLink.click()
  230. // document.body.removeChild(tempLink)
  231. // window.URL.revokeObjectURL(blobURL)
  232. // }
  233. // // Message({
  234. // // message: '请求下载文件失败,请稍后重试~',
  235. // // type: 'error',
  236. // // duration: 5 * 1000
  237. // // })
  238. // // }
  239. // })
  240. const get = (url, data = {}, config) => {
  241. config = pretreatConfig(config);
  242. return formatResponse(
  243. axios.get(url, {
  244. ...config,
  245. params: data,
  246. paramsSerializer(params) {
  247. return qs.stringify(params, {
  248. arrayFormat: 'brackets'
  249. });
  250. }
  251. })
  252. );
  253. };
  254. const del = (url, data = {}, config, type) => {
  255. config = pretreatConfig(config);
  256. return formatResponse(
  257. axios.delete(url, {
  258. ...config,
  259. params: data,
  260. paramsSerializer(params) {
  261. return qs.stringify(params, {
  262. arrayFormat: 'brackets'
  263. });
  264. }
  265. })
  266. );
  267. };
  268. const delData = (url, data = {}, params, config) => {
  269. config = pretreatConfig(config);
  270. return formatResponse(
  271. axios.delete(url, {
  272. ...config,
  273. data: data,
  274. params: params,
  275. paramsSerializer(params) {
  276. return qs.stringify(params, {
  277. arrayFormat: 'brackets'
  278. });
  279. }
  280. })
  281. );
  282. };
  283. const post = (url, data = {}, config) => {
  284. config = pretreatConfig(config);
  285. config = Object.assign(
  286. {
  287. headers: {
  288. 'Content-Type': 'application/json; charset=UTF-8'
  289. }
  290. },
  291. config
  292. );
  293. return formatResponse(
  294. axios.post(
  295. url,
  296. {
  297. data,
  298. seq: config.seq,
  299. token: config.token,
  300. limit: data.limit,
  301. start: data.start
  302. },
  303. config
  304. )
  305. );
  306. };
  307. const postData = (url, data = {}, config) => {
  308. config = pretreatConfig(config);
  309. config = Object.assign(
  310. {
  311. headers: {
  312. 'Content-Type': 'multipart/form-data; charset=UTF-8'
  313. }
  314. },
  315. config
  316. );
  317. return formatResponse(axios.post(url, data, config));
  318. };
  319. const put = (url, data = {}, config) => {
  320. config = pretreatConfig(config);
  321. config = Object.assign(
  322. {
  323. headers: {
  324. 'Content-Type': 'application/json; charset=UTF-8'
  325. }
  326. },
  327. config
  328. );
  329. return formatResponse(
  330. axios.put(url, { data, seq: config.seq, token: config.token }, config)
  331. );
  332. };
  333. /* 上方注释函数 */
  334. // export const download = (url, data = {}, config, name) => {
  335. // config = pretreatConfig(config)
  336. // config = Object.assign({
  337. // headers: {
  338. // 'Content-Type': 'application/json'F
  339. // },
  340. // responseType: 'blob'
  341. // }, config)
  342. // // return formatDownload(axios.post(url, data, config), name)
  343. // return formatDownload(axios.post(url, data, config), name)
  344. // }
  345. // export default axios;
  346. export default {
  347. get,
  348. post,
  349. postData,
  350. del,
  351. put,
  352. delData
  353. // download
  354. };