首页>>前端>>Vue->什么是axios?为什么要封装axios?如何封装axios?

什么是axios?为什么要封装axios?如何封装axios?

时间:2023-11-30 本站 点击:0

一、什么是axios,有什么特性

描述

axios是一个基于promiseHTTP库,可以用在浏览器或者node.js中。本文围绕XHR。

axios提供两个http请求适配器,XHR和HTTP。XHR的核心是浏览器端的XMLHttpRequest对象;HTTP的核心是node的http.request方法。

特性:

从浏览器中创建XMLHttpRequests

从node.js创建http请求

支持promise API

拦截请求与响应

转换请求数据与响应数据

取消请求

自动转换JSON数据

客户端支持防御XSRF

背景

Vue2.0起,尤大宣布取消对vue-resource的官方推荐,转而推荐axios。现在axios已经成为大部分Vue开发者的首选,目前在github上有87.3k star。axios的熟练使用和基本封装也成为了vue技术栈系列必不可少的一部分。如果你还不了解axios,建议先熟悉 axios官网文档。

基本使用

安装

npminstallaxios-S

使用

importaxiosfrom'axios'//为给定ID的user创建请求axios.get('/user?ID=12345').then(function(response){console.log(response);}).catch(function(error){console.log(error);});//上面的请求也可以这样做axios.get('/user',{params:{ID:12345}}).then(function(response){console.log(response);}).catch(function(error){console.log(error);});

二、Vue项目中为什么要封装axios

axios的API很友好,可以在项目中直接使用。但是在大型项目中,http请求很多,且需要区分环境, 每个网络请求有相似需要处理的部分,如下,会导致代码冗余,破坏工程的可维护性扩展性

axios('http://www.kaifa.com/data',{//配置代码method:'GET',timeout:3000,withCredentials:true,headers:{'Content-Type':'application/json'},//其他请求配置...}).then((data)=>{//todo:真正业务逻辑代码console.log(data);},(err)=>{//错误处理代码if(err.response.status===401){//handleauthorizationerror}if(err.response.status===403){//handleserverforbiddenerror}//其他错误处理.....console.log(err);});

环境区分

请求头信息

请求类型

请求超时时间

timeout: 3000

允许携带cookie

withCredentials: true

响应结果处理

登录校验失败

无权限

成功

...

三、Vue项目中如何封装axios

axios文件封装在目录src/utils/https.js,对外暴露callApi函数

1、环境区分

callApi函数暴露prefixUrl参数,用来配置api url前缀,默认值为api

//src/utils/https.jsimportaxiosfrom'axios'exportconstcallApi=({url,...prefixUrl='api'})=>{if(!url){consterror=newError('请传入url')returnPromise.reject(error)}constfullUrl=`/${prefixUrl}/${url}`...returnaxios({url:fullUrl,...})}

看到这里大家可能会问,为什么不用axios提供的配置参数baseURL,原因是baseURL会给每个接口都加上对应前缀,而项目实际场景中,存在一个前端工程,对应多个服务的场景。需要通过不用的前缀代理到不同的服务,baseURL虽然能实现,但是需要二级前缀,不优雅,且在使用的时候看不到真实的api地址是啥,因为代理前缀跟真实地址混合在一起了

使用baseURL,效果如下

函数设置prefixUrl参数,效果如下

利用环境变量webpack代理(这里用vuecli3配置)来作判断,用来区分开发、测试环境。生产环境同理配置nginx代理

//vue.config.jsconsttargetApi1=process.env.NODE_ENV==='development'?"http://www.kaifa1.com":"http://www.ceshi1.com"consttargetApi2=process.env.NODE_ENV==='development'?"http://www.kaifa2.com":"http://www.ceshi2.com"module.exports={devServer:{proxy:{'/api1':{target:targetApi1,changeOrigin:true,pathRewrite:{'/api1':""}},'/api2':{target:targetApi2,changeOrigin:true,pathRewrite:{'/api2':""}},}}}

2、请求头

常见以下三种

(1)application/json

参数会直接放在请求体中,以JSON格式的发送到后端。这也是axios请求的默认方式。这种类型使用最为广泛。

//src/utils/https.jsimportaxiosfrom'axios'importqsfrom'qs'constcontentTypes={json:'application/json;charset=utf-8',urlencoded:'application/x-www-form-urlencoded;charset=utf-8',multipart:'multipart/form-data',}constdefaultOptions={headers:{Accept:'application/json','Content-Type':contentTypes.json,}}exportconstcallApi=({url,data={},options={},contentType='json',//json||urlencoded||multipartprefixUrl='api'})=>{...constnewOptions={...defaultOptions,...options,headers:{'Content-Type':options.headers&&options.headers['Content-Type']||contentTypes[contentType],},}const{method}=newOptionsif(method!=='get'&&method!=='head'){if(datainstanceofFormData){newOptions.data=datanewOptions.headers={'x-requested-with':'XMLHttpRequest','cache-control':'no-cache',}}elseif(options.headers['Content-Type']===contentTypes.urlencoded){newOptions.data=qs.stringify(data)}else{Object.keys(data).forEach((item)=>{if(data[item]===null||data[item]===undefined||data[item]===''){deletedata[item]}})//没有必要,因为axios会将JavaScript对象序列化为JSON//newOptions.data=JSON.stringify(data);}}returnaxios({url:fullUrl,...newOptions,})}

注意,在application/json格式下,JSON.stringify处理传参没有意义,因为axios会将JavaScript对象序列化为JSON,也就说无论你转不转化都是JSON

3、请求类型

请求类型参数为axiosoptionsmethod字段,传入对应的请求类型如postget等即可

不封装,使用原生axios时,发送带参数的get请求如下:

//src/service/index.jsimport{callApi}from'@/utils/https';exportconstdelFile=(params)=>callApi({url:`file/delete?systemName=${params.systemName}&menuId=${params.menuId}&appSign=${params.appSign}`,option:{method:'get',},});//或者exportconstdelFile=(params)=>callApi({url:'file/delete',option:{method:'get',params},});

官方文档如下

callApi函数暴露method参数,用来配置请求类型,默认值为get

当请求类型为get时,将callApi函数暴露的data参数,设置为options.params,从而参数自动拼接到url地址之后

//src/utils/https.jsimportaxiosfrom'axios'exportconstcallApi=({url,data={},method='get',options={},...prefixUrl='api'})=>{...constnewOptions={...,...options,method}...if(method==='get'){newOptions.params=data}...returnaxios({url:fullUrl,...newOptions,})}

4、请求超时时间

//src/utils/https.jsconstdefaultOptions={timeout:15000,}

5、允许携带cookie

//src/utils/https.jsconstdefaultOptions={withCredentials:true,}

6、响应结果处理

通过.then.catch()处理

这块需要跟服务端约定接口响应全局码,从而统一处理登录校验失败无权限成功等结果

比如有些服务端对于登录校验失败无权限成功等返回的响应码都是200,在响应体内返回的状态码分别是20001,20002,10000,在then()中处理

比如有些服务端对于登录校验失败无权限成功响应码返回401,403,200,在catch()中处理

importaxiosfrom'axios'//为给定ID的user创建请求axios.get('/user?ID=12345').then(function(response){console.log(response);}).catch(function(error){console.log(error);});//上面的请求也可以这样做axios.get('/user',{params:{ID:12345}}).then(function(response){console.log(response);}).catch(function(error){console.log(error);});0

上述方案在Message.error(xx)时,当多个接口返回的错误信息一致时,会存在重复提示的问题,如下图

优化方案,利用防抖,实现错误提示一次,更优雅

四、完整封装及具体使用

代码可访问本人的github

axios-ajax完整封装

importaxiosfrom'axios'//为给定ID的user创建请求axios.get('/user?ID=12345').then(function(response){console.log(response);}).catch(function(error){console.log(error);});//上面的请求也可以这样做axios.get('/user',{params:{ID:12345}}).then(function(response){console.log(response);}).catch(function(error){console.log(error);});1
importaxiosfrom'axios'//为给定ID的user创建请求axios.get('/user?ID=12345').then(function(response){console.log(response);}).catch(function(error){console.log(error);});//上面的请求也可以这样做axios.get('/user',{params:{ID:12345}}).then(function(response){console.log(response);}).catch(function(error){console.log(error);});2

具体使用

api管理文件在目录src/service下,index.js文件暴露其他模块,其他文件按功能模块划分文件

get请求带参数 自定义前缀代理不同服务 文件类型处理

五、总结

axios封装没有一个绝对的标准,且需要结合项目中实际场景来设计,但是毋庸置疑,axios-ajax的封装是非常有必要的。

原文地址:https://github.com/zxyue25/axios-ajax

其他文章:vue多工程间公共模块处理最佳实践

本文收录专栏【业务总结】旨在沉淀工作中遇到的问题,总结为最佳实践,欢迎关注✨


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Vue/3748.html