项目实践 - Axios进阶封装

开发 项目管理
axios二次封装:就是把大部分接口公共的参数配置提取出来统一进行处理。

[[403088]]

 axios二次封装解决了什么问题?(项目常用)

axios二次封装:就是把大部分接口公共的参数配置提取出来统一进行处理。

1、代码封装,重用性高,减少代码量,减低维护难度。

2、统一处理一些常规的问题一劳永逸,如http错误。

3、拦截请求和响应,提前对数据进行处理,如获取token,修改配置项。

Axios基础配置- 实践

1) 全局的 axios 默认值

  1. axios.defaults.baseURL = 'https://api.example.com'
  2. axios.defaults.headers.common['Authorization'] = AUTH_TOKEN; 
  3. axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'

2) 自定义实例默认值

  1. // 创建实例时设置配置的默认值 
  2. var instance = axios.create({ 
  3.   baseURL: 'https://api.example.com' 
  4. }); 
  5.  
  6. // 在实例已创建后修改默认值 
  7. instance.defaults.headers.common['Authorization'] = AUTH_TOKEN; 

3) 区分环境配置

  1. let env = "dev"
  2. switch (env) { 
  3.     case 'dev'
  4.         axios.defaults.baseURL = "http://127.0.0.1:8888"
  5.         break; 
  6.     case 'test'
  7.         axios.defaults.baseURL = "http://114.27.34.1:8888"
  8.         break; 
  9.     case 'pro'
  10.         axios.defaults.baseURL = "http://api.zhufeng.cn"
  11.         break; 

4) 数据格式配置

  1. axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded'
  2. // axios.defaults.headers.common['Content-Type'] = 'application/x-www-form-urlencoded'
  3. // axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
  4. axios.defaults.transformRequest = function (data, headers) { 
  5.     let ContentType = headers['Content-Type'] || headers.common['Content-Type'] || headers.post['Content-Type'] || 'application/json'
  6.  
  7.     if (ContentType === "application/json") { 
  8.         return JSON.stringify(data); 
  9.     } 
  10.  
  11.     if (ContentType === "application/x-www-form-urlencoded") { 
  12.         return Qs.stringify(data); 
  13.     } 
  14.     return data; 
  15. }; 

项目实践-数据格式

  1. service.interceptors.request.use( 
  2.   (config) => { 
  3.     // 开发环境引入包装api 
  4.     config.url = `${BASE_URL}${config.url}`; 
  5.     config.headers['Cache-Control'] = 'no-cache,no-store,must-revalidate,max-age=-1,private'
  6.     // post请求并且需要将data以form data 形式传给后端 需要传一个formType为true boolean 
  7.     if (config.method === 'post' && config.formType === true) { 
  8.       config.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
  9.       config.data = qs.stringify(config.data); 
  10.     } 
  11.     return config; 
  12.   }, 
  13.   (error) => { 
  14.     // Do something with request error 
  15.     Promise.reject(error); 
  16.   } 
  17. ); 

5) 拦截器

  1. // 添加请求拦截器 
  2. axios.interceptors.request.use(function (config) { 
  3.     // 在发送请求之前做些什么 
  4.     return config; 
  5. }, function (error) { 
  6.     // 对请求错误做些什么 
  7.     return Promise.reject(error); 
  8. }); 
  9.  
  10. // 添加响应拦截器 
  11. axios.interceptors.response.use(function (response) { 
  12.     // 对响应数据做点什么 
  13.     return response; 
  14. }, function (error) { 
  15.     // 对响应错误做点什么 
  16.     return Promise.reject(error); 
  17. }); 

6) 响应的错误处理封装

interceptor作用就是拦截,可以针对请求参数和响应结果进行拦截处理,一般在项目当中,主要针对接口常规报错、网络报错、系统超时、权限认证等做拦截处理。

  1. axios.interceptors.response.use(function (response) { 
  2.     // 把获取的响应主体信息返回 
  3.     return response.data; 
  4. }, function (reason) { 
  5.     // 失败:网络、状态码(Axios失败) 
  6.     let response = reason.response; 
  7.     if (response) { 
  8.         // 状态码不是2开头的 
  9.         switch (response.status) { 
  10.             //400 参数 
  11.             //401/403 Token 
  12.             //404 地址 
  13.             //500/503 服务器 
  14.         } 
  15.     } else { 
  16.         // 网络 / (超时 / 中断请求  -> code: "ECONNABORTED") ... 
  17.         if (reason && reason.code === "ECONNABORTED") {} 
  18.         if (!navigator.onLine) {} 
  19.     } 
  20.     return reason; 
  21. }); 

一般项目,这样就没问题了,一套公共的参数配置。剩下都是请求的时候单独再配置即可。

Axios配置- 原理与源码

1) HTTP 拦截器的设计与实现

对于大多数 SPA 应用程序来说, 通常会使用 token 进行用户的身份认证。这就要求在认证通过后,我们需要在每个请求上都携带认证信息。如果在考虑对响应进行统一处理的话,我们的 request 函数将变得越来越庞大,也越来越难维护。那么对于这个问题,Axios 为我们提供了解决方案 —— 拦截器。

Axios 是一个基于 Promise 的 HTTP 客户端,而 HTTP 协议是基于请求和响应:

所以 Axios 提供了请求拦截器和响应拦截器来分别处理请求和响应。

1) 请求拦截器:该类拦截器的作用是在请求发送前统一执行某些操作,比如在请求头中添加 token 字段。

2) 响应拦截器:该类拦截器的作用是在接收到服务器响应后统一执行某些操作,比如发现响应状态码为 401 时,自动跳转到登录页。

2) 二次封装配置代码:(参考)

  1. import axios from 'axios'
  2. import qs from 'qs'
  3. /* 
  4.  * 根据环境变量区分接口的默认地址  
  5. */ 
  6. switch (process.env.NODE_ENV) { 
  7.     case "production"
  8.         axios.defaults.baseURL = "http://api.zhufengpeixun.cn"
  9.         break; 
  10.     case "test"
  11.         axios.defaults.baseURL = "http://192.168.20.12:8080"
  12.         break; 
  13.     default
  14.         axios.defaults.baseURL = "http://127.0.0.1:3000"
  15.  
  16. /* 
  17.  * 设置超时时间和跨域是否允许携带凭证  
  18. */ 
  19. axios.defaults.timeout = 10000; 
  20. axios.defaults.withCredentials = true
  21.  
  22. /* 
  23.  * 设置请求传递数据的格式(看服务器要求什么格式) 
  24.  * x-www-form-urlencoded 
  25. */ 
  26. axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded'
  27. axios.defaults.transformRequest = data => qs.stringify(data); 
  28.  
  29. /* 
  30.  * 设置请求拦截器  
  31.  * 客户端发送请求 - > [请求拦截器] - > 服务器 
  32. * TOKEN校验(JWT):接收服务器返回的token,存储到vuex/本地存储中,每一次向服务器发请求,我们应该把token带上 
  33. */ 
  34. axios.interceptors.request.use(config => { 
  35.     // 携带上token 
  36.     let token = localStorage.getItem('token'); 
  37.     token && (config.headers.Authorization = token); 
  38.     return config; 
  39. }, error => { 
  40.    return Promise.reject(error); 
  41. }); 
  42.  
  43. /* 
  44.  * 响应拦截器  
  45.  * 服务器返回信息  -> [拦截的统一处理] -> 客户端JS获取到信息 
  46. */ 
  47. axios.defaults.validateStatus = status => { 
  48.     // 自定义响应成功的HTTP状态码 
  49.     return /^(2|3)\d{2}$/.test(status); 
  50. }; 
  51. axios.interceptors.response.use(response => { 
  52.     return response.data; 
  53. }, error => { 
  54.     let { 
  55.         response 
  56.     } = error; 
  57.     if (response) { 
  58.         //=>服务器最起码返回结果了 
  59.         switch (response.status) { 
  60.             case 401: //=>权限 
  61.                 break; 
  62.             case 403: //=>服务器拒绝执行(token过期) 
  63.                 break; 
  64.             case 404: //=>找不到页面  
  65.                 break; 
  66.         } 
  67.     } else { 
  68.         //=>服务器连结果都没有返回 
  69.         if (!window.navigator.onLine) { 
  70.             // 断网处理:可以跳转到断网页面 
  71.             return
  72.         } 
  73.         return Promise.reject(error); 
  74.     } 
  75. }); 
  76. export default axios; 

 【编辑推荐】

 

责任编辑:姜华 来源: 前端学苑
相关推荐

2022-04-22 10:51:45

TSaxios前端

2021-07-27 14:50:15

axiosHTTP前端

2020-10-19 19:05:20

VueAxiosAPI

2023-10-07 14:25:14

2020-07-17 19:55:50

Vue前端性能优化

2019-11-22 15:27:07

技术漏洞管理网络

2019-11-24 23:39:01

漏洞管理漏洞风险

2020-05-06 09:25:10

微前端qiankun架构

2022-09-28 12:39:46

axios拦截器

2020-06-12 07:00:00

Web开发项目

2023-09-05 08:21:07

项目CICD场景

2017-08-08 10:01:20

项目管理敏捷实践团队

2017-04-28 10:57:52

IT信息化服务器云计算

2022-12-30 11:46:00

数据中台

2024-04-18 09:20:43

PostgreSQL关系型数据库数据库管理系统

2021-03-02 08:00:00

项目管理组织工具

2023-08-28 07:28:41

项目领域层充血模型

2021-06-10 16:05:17

DevOpsGitLab极狐

2021-08-26 07:38:41

AndroidMediaPlayerTextureView

2024-12-17 08:04:04

点赞
收藏

51CTO技术栈公众号