摘要:使用了拦截器处理相关问题,这样就不再需要使用来做错误的处理。万恶的拦截器一些处理无论是对成功的处理还是对失败的处理,如果拦截器不抛出错误,那么终将还会执行里面处理请求成功的函数,即使你返回。
一 前言
本文适合刚接触axios或者使用过几次的同学来分享交流一些入门经验,本文同样适用熟悉axios的同学来作为参考手册。
默认你已经看过axios的相关文档:axios文档 GitHub,通过文档了解基础的使用之后,接下来你可以进入正文。
axios = Ajax + 异步处理
1.axios的get与post方法传入参数的区别(1)get
axios.get("/user", { params: { ID: 12345 } }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
(2)post
axios.post("/user", { firstName: "Fred", lastName: "Flintstone" }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
get是放在参数对象的params属性里面,post是直接放在参数对象里面。
2.学会使用axios.create( )创建axios实例var instance = axios.create({ baseURL: "https://some-domain.com/api/", timeout: 1000, headers: {"X-Custom-Header": "foobar"} });
创建实例的好处:统一(批量)处理request/response
(1)例如你在每次的请求中都要带 cookie, 你或许可以在每个请求中这么写:
axios.get("/user1",{withCredentials:true}); axios.get("/user2",{withCredentials:true}); ... ...
但是你也可以这么用:
var instance = axios.create({ withCredentials:true }); instance.get("/user1").then(); instance.get("/user2").then(); ... ...
(2)如果你的多个请求前缀都是相同的,那么你就可以使用baseUrl
bad:
axios.get("http://www.baidu.com/api/city").then(); axios.get("http://www.baidu.com/api/region").then(); axios.get("http://www.baidu.com/api/user").then();
good:
var instance = axios.create({ baseUrl: http://www.baidu.com/api }); instance.get("/city").then(); instance.get("/region").then(); instance.get("/user").then();
(3)其他方法推荐
设置超时时间:timeout
设置报文头:header
等等
(1)使用与取消
我们可以这么用:
// 添加请求拦截器 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); });
建议将拦截器挂在到实例上:
var instance = axios.create(); instance.interceptors.request.use(function () {/*...*/});
如果你想在稍后移除拦截器,可以这样:
var myInterceptor = axios.interceptors.request.use(function () {/*...*/}); axios.interceptors.request.eject(myInterceptor);
(2)注意事项
拦截器可以拦截请求和拦截响应,在请求或响应被 then 或 catch 处理前拦截它们。
它接受两个函数类型的参数,一个是成功请求/返回的函数,一个是失败请求/返回的函数;可以在这些函数里面做一些事情,例如对于401未授权的错误,我们可以重定向到登陆页:
instance.interceptors.response.use(function (res) { return res; },function(error){ if (error.response.status === 401) { login(); return; } });
需要记住的是一旦你返回成功,如果没什么事可做,其他的事交给then之后来做,记得返回response/request,不然then接受不到响应。
(3)使用了拦截器处理相关问题,这样就不再需要使用catch来做错误的处理。
4.万恶的拦截器instance.interceptors.response.use(function (res) { return res; },function(error){ if (error.response.status === 401) { /*一些处理*/ throw error; } });
无论是对成功的处理还是对失败的处理,如果拦截器不抛出错误throw error,那么终将还会执行then里面处理请求成功的函数,即使你返回undefined。
所以,建议在错误处理的最后抛出错误!
转载文章链接:https://juejin.im/post/5a293e...
//引入axios import axios from "axios" let cancel ,promiseArr = {} const CancelToken = axios.CancelToken; //请求拦截器 axios.interceptors.request.use(config => { //发起请求时,取消掉当前正在进行的相同请求 if (promiseArr[config.url]) { promiseArr[config.url]("操作取消") promiseArr[config.url] = cancel } else { promiseArr[config.url] = cancel } return config }, error => { return Promise.reject(error) }) //响应拦截器即异常处理 axios.interceptors.response.use(response => { return response }, error => { if (error && error.response) { switch (error.response.status) { case 400: error.message = "错误请求" break; case 401: error.message = "未授权,请重新登录" break; case 403: error.message = "拒绝访问" break; case 404: error.message = "请求错误,未找到该资源" break; case 405: error.message = "请求方法未允许" break; case 408: error.message = "请求超时" break; case 500: error.message = "服务器端出错" break; case 501: error.message = "网络未实现" break; case 502: error.message = "网络错误" break; case 503: error.message = "服务不可用" break; case 504: error.message = "网络超时" break; case 505: error.message = "http版本不支持该请求" break; default: error.message = `连接错误${error.response.status}` } } else { error.message = "连接到服务器失败" } Message.error(error);//Message 一个UI提示组件 return Promise.resolve(error.response) }) axios.defaults.baseURL = "/api" //设置默认请求头 axios.defaults.headers = { "X-Requested-With": "XMLHttpRequest" } axios.defaults.timeout = 10000 export default { //get请求 get (url,param) { return new Promise((resolve,reject) => { axios({ method: "get", url, params: param, cancelToken: new CancelToken(c => { cancel = c }) }).then(res => { resolve(res) }) }) }, //post请求 post (url,param) { return new Promise((resolve,reject) => { axios({ method: "post", url, data: param, cancelToken: new CancelToken(c => { cancel = c }) }).then(res => { resolve(res) }) }) } }
注意:这段代码中没有创建axios实例,个人觉得创建实例会更方便调用。
根据官方文档,如何取消一个尚未得到响应的请求:
var CancelToken = axios.CancelToken; var cancel; axios.get("/user/12345", { cancelToken: new CancelToken(function executor(c) { // An executor function receives a cancel function as a parameter cancel = c; }) }); // cancel the request cancel();6.axios 失败重新请求的封装
//在main.js设置全局的请求次数,请求的间隙 axios.defaults.retry = 4; axios.defaults.retryDelay = 1000; axios.interceptors.response.use(undefined, function axiosRetryInterceptor(err) { var config = err.config; // If config does not exist or the retry option is not set, reject if (!config || !config.retry) return Promise.reject(err); // Set the variable for keeping track of the retry count config.__retryCount = config.__retryCount || 0; // Check if we"ve maxed out the total number of retries if (config.__retryCount >= config.retry) { // Reject with the error return Promise.reject(err); } // Increase the retry count config.__retryCount += 1; // Create new promise to handle exponential backoff var backoff = new Promise(function (resolve) { setTimeout(function () { resolve(); }, config.retryDelay || 1); }); // Return the promise in which recalls axios to retry the request return backoff.then(function () { return axios(config); }); });7.更实用的封装
通常不需要请求失败之后再重新请求
请求失败之后不需要把错误提示的那么详细
通常在请求时还伴随加载状态【重要】
示例代码:
// 创建axios实例 const axiosInstance = axios.create({ // timeout: 3000, // baseURL, withCredentials: true, }); // request拦截器 axiosInstance.interceptors.request.use((config) => config, (error) => Promise.reject(error)); axiosInstance.interceptors.response.use((response:AxiosResponse)=> { const {data} = response || {data:{}}; return Promise.resolve(data); }, (error:any) => { if(error&&error.response){ // 提示具体接口报错 return Promise.resolve(error.response); }else{ const response = { code:1, // 表示错误的code码 message:"网络连接错误", } // 提示“网络连接错误” return Promise.resolve(response); } }); export default axiosInstance;
和上面的参考封装有以下不同之处:
拦截器里只抛出网络连接失败的错误
无论服务器返回的请求是成功(200)还是失败(404 500等),都会被resolve,这就会有三点影响:
业务逻辑上.then(()=>{})的时候都会走resolve的函数,这样就可以在这个函数里控制loading状态
resolve的函数需要根据后端response的成功标示来判断请求是成功还是失败
这样就不再需要.catch()
三 后记简单的介绍了一些常见事项和基础用法,有更多的内容等待大家去探索,欢迎留言交流~~
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/90468.html
摘要:说起,其实早在出现之前,网页就是在服务端渲染的。没有涉及流式渲染组件缓存对的服务端渲染有更深一步的认识,实际在生产环境中的应用可能还需要考虑很多因素。选择的服务端渲染方案,是情理之中的选择,不是对新技术的盲目追捧,而是一切为了需要。 作者:威威(沪江前端开发工程师)本文原创,转载请注明作者及出处。 背景 最近, 产品同学一如往常笑嘻嘻的递来需求文档, 纵使内心万般拒绝, 身体倒是很诚实...
平日学习接触过的网站积累,以每月的形式发布。2017年以前看这个网址:http://www.kancloud.cn/jsfron... 1. Javascript 前端生成好看的二维码 十大经典排序算法(带动图演示) 为什么知乎前端圈普遍认为H5游戏和H5展示的JSer 个人整理和封装的YU.js库|中文详细注释|供新手学习使用 扩展JavaScript语法记录 - 掉坑初期工具 汉字拼音转换...
平日学习接触过的网站积累,以每月的形式发布。2017年以前看这个网址:http://www.kancloud.cn/jsfron... 1. Javascript 前端生成好看的二维码 十大经典排序算法(带动图演示) 为什么知乎前端圈普遍认为H5游戏和H5展示的JSer 个人整理和封装的YU.js库|中文详细注释|供新手学习使用 扩展JavaScript语法记录 - 掉坑初期工具 汉字拼音转换...
平日学习接触过的网站积累,以每月的形式发布。2017年以前看这个网址:http://www.kancloud.cn/jsfron... 1. Javascript 前端生成好看的二维码 十大经典排序算法(带动图演示) 为什么知乎前端圈普遍认为H5游戏和H5展示的JSer 个人整理和封装的YU.js库|中文详细注释|供新手学习使用 扩展JavaScript语法记录 - 掉坑初期工具 汉字拼音转换...
平日学习接触过的网站积累,以每月的形式发布。2017年以前看这个网址:http://www.kancloud.cn/jsfron... 1. Javascript 前端生成好看的二维码 十大经典排序算法(带动图演示) 为什么知乎前端圈普遍认为H5游戏和H5展示的JSer 个人整理和封装的YU.js库|中文详细注释|供新手学习使用 扩展JavaScript语法记录 - 掉坑初期工具 汉字拼音转换...
阅读 2219·2021-11-18 10:02
阅读 3478·2021-11-15 11:36
阅读 1114·2019-08-30 14:03
阅读 722·2019-08-30 11:08
阅读 2760·2019-08-29 13:20
阅读 3287·2019-08-29 12:34
阅读 1374·2019-08-28 18:30
阅读 1640·2019-08-26 13:34