项目实践 - Axios进阶封装

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

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

1、实践代码封装,进阶封重用性高,项目减少代码量,实践减低维护难度。进阶封

2、项目统一处理一些常规的实践问题一劳永逸,如http错误。进阶封

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

Axios基础配置- 实践

1) 全局的进阶封 axios 默认值

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

2) 自定义实例默认值

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

3) 区分环境配置

let env = "dev"; switch (env) {      case dev:         axios.defaults.baseURL = "http://127.0.0.1:8888";         break;     case test:         axios.defaults.baseURL = "http://114.27.34.1:8888";         break;     case pro:         axios.defaults.baseURL = "http://api.zhufeng.cn";         break; } 

4) 数据格式配置

axios.defaults.headers[Content-Type] = application/x-www-form-urlencoded; // axios.defaults.headers.common[Content-Type] = application/x-www-form-urlencoded; // axios.defaults.headers.post[Content-Type] = application/x-www-form-urlencoded; axios.defaults.transformRequest = function (data, headers) {      let ContentType = headers[Content-Type] || headers.common[Content-Type] || headers.post[Content-Type] || application/json;     if (ContentType === "application/json") {          return JSON.stringify(data);     }     if (ContentType === "application/x-www-form-urlencoded") {          return Qs.stringify(data);     }     return data; }; 

项目实践-数据格式

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

5) 拦截器

// 添加请求拦截器 axios.interceptors.request.use(function (config) {      // 在发送请求之前做些什么     return config; }, function (error) {      // 对请求错误做些什么     return Promise.reject(error); }); // 添加响应拦截器 axios.interceptors.response.use(function (response) {      // 对响应数据做点什么     return response; }, function (error) {      // 对响应错误做点什么     return Promise.reject(error); }); 

6) 响应的错误处理封装

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

axios.interceptors.response.use(function (response) {      // 把获取的响应主体信息返回     return response.data; }, function (reason) {      // 失败:网络、状态码(Axios失败)     let response = reason.response;     if (response) {          // 状态码不是2开头的         switch (response.status) {              //400 参数             //401/403 Token             //404 地址             //500/503 服务器         }     } else {          // 网络 / (超时 / 中断请求  -> code: "ECONNABORTED") ...         if (reason && reason.code === "ECONNABORTED") { }         if (!navigator.onLine) { }     }     return reason; }); 

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

Axios配置- 原理与源码

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

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

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

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

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

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

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

import axios from axios; import qs from qs; /*  * 根据环境变量区分接口的默认地址  */ switch (process.env.NODE_ENV) {      case "production":         axios.defaults.baseURL = "http://api.zhufengpeixun.cn";         break;     case "test":         axios.defaults.baseURL = "http://192.168.20.12:8080";         break;     default:         axios.defaults.baseURL = "http://127.0.0.1:3000"; } /*  * 设置超时时间和跨域是否允许携带凭证  */ axios.defaults.timeout = 10000; axios.defaults.withCredentials = true; /*  * 设置请求传递数据的格式(看服务器要求什么格式)  * x-www-form-urlencoded */ axios.defaults.headers[Content-Type] = application/x-www-form-urlencoded; axios.defaults.transformRequest = data => qs.stringify(data); /*  * 设置请求拦截器   * 客户端发送请求 - > [请求拦截器] - > 服务器 * TOKEN校验(JWT):接收服务器返回的token,存储到vuex/本地存储中,每一次向服务器发请求,我们应该把token带上 */ axios.interceptors.request.use(config => {      // 携带上token     let token = localStorage.getItem(token);     token && (config.headers.Authorization = token);     return config; }, error => {     return Promise.reject(error); }); /*  * 响应拦截器   * 服务器返回信息  -> [拦截的统一处理] -> 客户端JS获取到信息 */ axios.defaults.validateStatus = status => {      // 自定义响应成功的HTTP状态码     return /^(2|3)\d{ 2}$/.test(status); }; axios.interceptors.response.use(response => {      return response.data; }, error => {      let {          response     } = error;     if (response) {          //=>服务器最起码返回结果了         switch (response.status) {              case 401: //=>权限                 break;             case 403: //=>服务器拒绝执行(token过期)                 break;             case 404: //=>找不到页面                  break;         }     } else {          //=>服务器连结果都没有返回         if (!window.navigator.onLine) {              // 断网处理:可以跳转到断网页面             return;         }         return Promise.reject(error);     } }); export default axios; 

 【编辑推荐】

接入网究竟是个什么网 程序员年龄增大后的职业出路是什么? 从源码中来,到业务中去,React性能优化终极指南 等了这么久,谷歌终于推出Fuchsia OS了 GC详解,云服务器看完这篇同事小勇都惊呆了
数据库
上一篇:Arm收购Raspberry Pi少数股权 合作开发物联网解决方案
下一篇:戴尔科技借助边缘计算等技术,助力农业生产向智慧化转型