首页 > 其他分享 >axios之基本封装

axios之基本封装

时间:2023-12-26 16:23:09浏览次数:40  
标签:基本 axios 封装 请求 error catch return response

1. axios实例

安装axios库 npm install axios or yarn add axiosor CDN <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

// 引入
import axios from 'axios' // 库
import Cookies from 'js-cookie'
import { Notification, MessageBox, Message, Loading } from 'element-ui'
import { getToken } from '@/utils/auth' // 分别暴露

// 创建axios实例
const service = axios.create({
	baseURL: process.env.VUE_APP_BASE_API,
	timeout:, // 设置网络超时时间(不同于建立连接超时,而是多久得不到后台的返回数据)
	// ...
})

// ...

export default service 

2. 请求拦截器

// 请求拦截器
service.interceptors.request.use(
  config => {
    // 1. 配置用户标识,需要判断本地是否存在 token,每个请求都带上给后端验证 token(失效or过期)
    if (getToken()) { // localStorage.sessionId
      config.headers['Authorization'] = getToken() 
    }
    // 2.调整请求
	// 配置请求头,请求体中的数据会以 json 字符串的形式发送到后端,axios请求类型默认就是这个编码格式,http默认的是application/x-www-form-urlencoded
    config.headers['Content-Type'] = '’application/json;charset=utf-8' // 会进行JSON序列化( JS 对象 ==> JSON 字符串 )
    // 3. 根据需求添加请求头
	if () {
	  config.headers['xxx'] = Cookies.get('xxx')
	}
    return config
  },
  error => {
	  // 暂时没找到【主动】触发第二个回调的方法
	  Promise.reject(error)
  }
)

auth.js

import Cookies from 'js-cookie'
import Config from '@/settings'

const TokenKey = Config.TokenKey
export function getToken() {
  return Cookies.get(TokenKey)
}

2. 响应拦截器的两个函数参数的参数

2.1 response对象的结构

ajax请求对象

response: {
	config:{}, // 请求配置对象
	headers:{}, // 响应头
	request:{
		readyState:4,// 0/1/2/3/4
		responseType:'',
		status:200,
		statusText:''
	} // 原生ajax请求对象
	statusText:'',
	status:200, // 响应状态码,http协议规定
	data:{
		{  
			code:0, // 业务状态码,后端约定
			data:{},
			message:''
		 }
	}, // data 才是后台接口代码中的 return 值!
}

2.2 error对象的结构

{
	message:'', // 错误信息
	code:'', // 网络超时会有这个属性,被设置为ECONNABORTED
	response:{}, // 非网络超时才有,响应对象,同上
	// ...
}

3. 响应拦截器

// 响应拦截器
service.interceptors.response.use(
	response => {
		// 只要请求响应的状态码,response.status 为 2xx,即会触发这个回调
		// 二进制数据则直接返回
	    if(response.request.responseType ===  'blob' || response.request.responseType ===  'arraybuffer'){
	      return response.data 
	    }
		// 注意,如登录:输入的用户密码错误时,请求响应成功,状态码是200,一般是response.data里设置code或success字段,用0/1来表示业务上的成功与否。
		// 此处就这样返回,具体业务中就需要每次都逻辑判断code或success的情况
		// return response.data
		// 此处假设业务状态码的键为code,0为成功、1为失败;业务消息为msg,因为进到这个回调里的肯定是2xx,所以这里处理的是业务or逻辑上的错误
		// 怎么感觉没有什么必要啊,不同的业务不是会有不同的处理吗
		const { code, msg, data } = response.data || {}
		if() {
			return Promise.reject('error')
			Message.error(msg ? msg : 'xxx') 
		} else if() {
			return Promise.reject('error')
			Message.error(msg ? msg : 'xxx') 
		} else {
			return data 
		}
	},
	error => {
		// 其它情况
		if(){
		}
		// 请求完全得不到响应,如网络超时(timeout)会触发这个回调
		// 请求响应的状态码超出2xx,如404、500...会触发这个回调
		else {
			try {
				// 拿到响应状态码
				const status = error.response.status
			} catch(err) {
				// axios中,网络超时(timeout),error 对象只有 code 和 message 属性,因此 error.response.status 会报错,需捕获异常
				if(error.code === 'ECONNABORTED' || error.message === "Network Error" ||  error.message.includes("timeout"){
					Message({
						message: '网络超时,请稍后重试',
						type: 'error',
						duration: 3000
					})
				}
			}
			let errMsg = '未知错误' 
			switch(status){
				case 401:
					errMsg = '未授权,请重新登录'
					// 授权错误:登录用户的token无or无效or过期
					// 登出用户、跳转至登录页
					// ...
					break;
				case 403:
					errMsg = '拒绝访问' // 与用户访问服务器资源权限有关
					break;
				case 408:
					errMsg = '请求超时' // 指的是服务器等候请求时发生超时
					break;	
				case 500:
					errMsg = '服务端出错'
					break;
				case 502:
					errMsg = '网关错误'
					break;
				default:
					errMsg = `其它连接错误:${status}`
					break;
				
			}
			Message.error(errMsg)
		}
		// 取消请求,如CancelToken,可以用axios.isCancel(err)来判断是否是取消的请求
		else if(axios.isCancel(err)) {
			// 处理
		}
		// 请求运行有异常也会进入这里,如故意将headers写错:axios.defaults.headers = '123',或者在request中有语法或解析错误也会进入这里
		// ...
		// 以上的所有情况都要返回一个reject的Promise
		return Promise.reject(error)
	}
)

JSON 是 JS 对象的字符串表示法,JS对象转JSON:JSON.stringify(obj) ,JSON转JS :JSON.parse(text); 也可以用于深拷贝对象

4. 接口调用

// 接口
 export function getList(form) {
	 return request({
		 url:'',
		 method:'',
		 data:form
	 })
 }

// 调用
// getList() === > request() 函数执行,可以理解为new Promise了 === > 拦截器相当于链式调用 ==> res接收响应拦截器设置的返回值 data,err接收Promise.reject(error)
getList().then(res => {
	console.log(res) // { code:0,data:{},msg:'返回成功!'}
}).catch(err => {
	// 响应拦截器 return Promise.reject(error)就会走catch,或者是代码错误(then阶段处理逻辑代码出错也会catch哦)
	console.log(err) // 捕获响应拦截器的error对象,一般情况下如果响应拦截器对错误处理进行了封装,可以不捕获异常,除非then回调里可能出现问题~
})

附:Promise.then().catch() 和 第二个回调的区别

主要区别就是:如果在 .then 的第一个函数里抛出的异常,后面的 .catch 能捕获到,而 .then 的第二个函数捕获不到;

  1. resolve 后的,一定会进入 then 的第一个回调,肯定不会进入 catch
  2. reject 后的,一定会进入 then 中的第二个回调,如果 then 中没有写第二个回调,则进入 catch
  3. new Promise 时抛出的异常,如果 .then 有第二个回调,是会就近捕获的
  4. then 第一个回调内抛出的异常,只有 catch 可以捕获
// 4示例
const p1 = new Promise((resolve, reject) => {
  resolve('成功!');
});

p1.then(
  (value) => {
    console.log(value); // "成功!"
    throw new Error('噢,不!');
  },
  (err) => {
    console.log(err.message, 'then2');
  }
).catch((e) => {
  console.error(e.message, 'catch'); // "噢,不!"
});
// 3示例
const p1 = new Promise((resolve, reject) => {
  throw new Error('errrr');
  resolve('成功!');
});

p1.then(
  (value) => {
    console.log(value); 
  },
  (err) => {
    console.log(err.message, 'then2'); // errrr then2
  }
).catch((e) => {
  console.error(e.message, 'catch'); 
});

附:axios的post请求像get请求一样,不在请求体中携带数据而是在路径中传参

getById(id){
	return request({
		  url:`xxx/getById`, // get 是 `/${}`
		  method: 'get',
		  params:{
			id // post
		  }
	})
},

标签:基本,axios,封装,请求,error,catch,return,response
From: https://www.cnblogs.com/pupyy/p/17928335.html

相关文章

  • 【Python微信机器人】第六七篇: 封装32位和64位Python hook框架实战打印微信日志
    目录修整目前的系列目录(后面会根据实际情况变动):在windows11上编译python将python注入到其他进程并运行注入Python并使用ctypes主动调用进程内的函数和读取内存结构体调用汇编引擎实战发送文本和图片消息(支持32位和64位微信)允许Python加载运行py脚本且支持热加载利用......
  • NX2306 运动仿真-基本认知【机电设计概念】
    【写在每个笔记前面:个人学习记录,如有错误,烦请指正,不胜感激。】 思路:1、基本认知---对基础功能键的了解。(本篇内容) 基本对象:a、刚体:b、碰撞体:  2、真正设置一个运动之前,先理清楚运动流程、联动状态,固定块等?(没啥好讲的,反正就是每次操作之前自己理吧。) ......
  • 【flink番外篇】6、flink的WaterMark(介绍、基本使用、kafka的水印以及超出最大允许延
    Flink系列文章一、Flink专栏Flink专栏系统介绍某一知识点,并辅以具体的示例进行说明。1、Flink部署系列本部分介绍Flink的部署、配置相关基础内容。2、Flink基础系列本部分介绍Flink的基础部分,比如术语、架构、编程模型、编程指南、基本的datastreamapi用法、四大基......
  • 使用Go语言编写基本的HTTP服务器
    你是否曾经想过自己动手编写一个Web服务器?那种可以接收来自全世界的请求,然后回应一些“Hello,World!”之类的消息的服务器?如果你有这个想法,那么Go语言就是你的最佳伙伴。让我们一起踏上这段奇妙的探险之旅吧!首先,你需要安装Go语言环境。这就像给你的电脑安装一个魔法水晶球,让它拥有......
  • 【译文】IEEE白皮书 6G 太赫兹技术的基本原理 2023版
    第一章简介太赫兹波是介于微波和光波之间的光谱区域,频率从0.1THz~10THz之间,波长在3mm~30μm之间。提供大块连续的频带范围以满足对Tbit/s内极高数据传输速率的需求,使该区域成为下一代无线通信(6G)的重点研究领域。预计在2030年左右实现商业部署,太赫兹区域在成像、光谱......
  • 2数据库之Mysql基本操作
                                                                                                      数据库基本类型、基本操作一.......
  • Java基本结构
    Java基本结构1.顺序结构​ Java的基本结构就是顺序结构,除非特别指明,否则代码就是一行一行执行。2.选择结构if选择结构switch选择结构packagecom.wenxuan.structure;publicclassD1Switch{publicstaticvoidmain(String[]args){//case穿透,如果没有......
  • 软件开发有哪些基本常识?
    软件开发的定义:软件开发是指使用计算机语言编写程序,将计算机硬件与软件相结合,实现某种功能的过程。软件开发的流程:通常包括需求分析、设计、编码、测试、部署和维护等环节。需求分析:在软件开发过程中,需求分析是一个非常重要的环节,它是指通过与客户沟通、了解客户需求,确定软件应该具......
  • 25、Flutter中基本路由
    Flutter路由介绍Flutter中的路由通俗的讲就是页面跳转。在Flutter中通过Navigator组件管理路由导航。并提供了管理堆栈的方法。如:Navigator.push和Navigator.popFlutter中给我们提供了两种配置路由跳转的方式:1、基本路由2、命名路由Flutter中的基本路由使用想从HomePage......
  • Unity引擎2D游戏开发,野猪基本的移动逻辑和动画
    一、类的继承在Scripts下创建Enemy文件夹,里面再创建两个C#文件将Boar文件内的代码修改为以下代码,:后的是Enemy,即继承了Enemy类publicclassBoar:Enemy{}在Enemy内,编写基本属性publicclassEnemy:MonoBehaviour{[Header("基本参数")]//基本移动速度......