Vue项目总结(4)-API+token处理流程
2020/3/2 11:15:58
本文主要是介绍Vue项目总结(4)-API+token处理流程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
本文介绍了一些Vue和axios的实用技巧,解决前端API调用中access_token的处理问题,包括:Promise的链式调用,axios的拦截器,vue-router记录导航历史等。
问题分析
前后端完全分离的项目中,一个前端应用会访问多个后端的API,API调用都要通过传递token进行用户身份认证。用户登录就是用用户名和口令换取token,获得token后前端自行保留(例如:放在sessionStorage里),然后每次发起API调用时添加上这个参数。为了安全,token会设置有效期,过期了就需要重新登录获取新的token。我们可以看到用户登录流程设计的核心,其实就是一个管理和使用token的问题。
基于token的使用,需要考虑如下情况:
- 进入页面,页面内同时发起多个API调用
- 用户在页面中执行操作,操作中发起多个API调用,例如:提交表单
- 调用API,本地没有token,打开登录页
- 调用API,本地有token,API调用返回token已经过期,打开登录页
- 调用API,其他请求正在获取token,停止或取消调用
- 调用认证API,不添加token
- 登录成功后,保存获得的token,关闭登录,重新发起API调用
这里面临几个技术问题:
- 前端本地存储token;
- 区分API调用是否需要添加token;
- 如果同时发出多个请求,当其中的一个已经开始获取token,如何取消或暂停其它请求;
- 登录后完成后,如何自动回到之前的状态。
理解axios拦截器
为了满足上面提到的要求,需要能够控制API请求的执行过程,axios中是通过拦截器添加控制逻辑,因为我们先深入了解一下axios中拦截器的相关代码。
// Hook up interceptors middleware var chain = [dispatchRequest, undefined]; var promise = Promise.resolve(config); this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { chain.unshift(interceptor.fulfilled, interceptor.rejected); }); this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { chain.push(interceptor.fulfilled, interceptor.rejected); }); while (chain.length) { promise = promise.then(chain.shift(), chain.shift()); } return promise; 复制代码
要理解上面的代码,首先要理解promise链式调用
和promise.then()
。
链式调用
prmise链式调用就将几个promise串起来执行,上一个promise执行的结果,作为下一个promise的输入。看个例子:
let p1 = Promise.resolve('a') let p2 = Promise.resolve('b') let p3 = Promise.resolve('c') let p4 p4 = p1.then(v1 => { console.log('then-1', v1) // 这个是第2行输出,输出a return p2.then(v2 => v1 + v2) }).then(v1 => { console.log('then-2', v1) // 这个是第3行输出,输出ab return p3.then(v2 => v1 +v2) }) p4.then(v => { console.log('then-3', v) // 这个是第4行输出,输出abc }) console.log('begin...') // 这个是第1行输出 复制代码
通过上面的方式就可以把多个异步操作串联起来执行。
then方法
Promise的then方法传入两个参数,分别在调用then方法的promise对象完成或失败时调用。注意这个调用是异步调用(需要去排队执行),这就是为什么上面的例子中最后1句console.log()
是第1个输出,因为then中的回调函数是排队执行的。
掌握then
方法的关键是理解返回值。首先,then
方法返回的是Promise
对象,这是可以进行链式调用的基础;第二,执行哪个回调函数由调用then的Promise对象的执行结果决定(两个回调函数之间没有关系);第三,返回的Promise对象的状态由执行的回调函数的返回值决定(和是哪个回调函数返回无关)。例如:回调函数内返回的是一个值(数字、字符串、对象等),那么生成的Promise对象的状态是完成(fulfilled)。具体规则请参考在线文档。
需要注意的是,失败回调函数只是当前执行的promise对象的结果,并不是整个链的结果,完成和失败回调函数都可以通过返回值,告诉下一个环节要进入完成函数还是失败函数。因此,链式调用中每一个环节都可以修正上一个环节的“错误”,继续让链执行。
这里有个有意思的问题:catch
一定是除finally
外最后执行的环节吗,它可以写在then
的前面吗?答案是可以。因为,catch
是then
的缩写,等价于then(undefined, err=>{...})
。
参考:developer.mozilla.org/zh-CN/docs/…
axios拦截器
明白了链式调用和then方法,axios的拦截器机制就好理解了。
while (chain.length) { promise = promise.then(chain.shift(), chain.shift()); } 复制代码
每条拦截规则都由完成函数(fulfilled)和失败函数(rejected)构成,可以理解为:请求的上一步成功了做什么,失败了又该做什么。这个理解很关键,因为添加拦截规则时容易想成:在完成函数中添加拦截逻辑,如果这个逻辑失败了,在失败函数中进行处理。完成函数发生异常,失败函数不会被执行,因为是否调用它不是由完成函数决定,而是由上一个执行环节的执行结果决定。完成函数的异常要在后续环节的失败函数中处理。
另外,需要注意的是,请求规则和响应规则的执行顺序不一样,请求规则是先定义的后执行(unshift),响应规则是先定义的先执行(push)。
再有,请求规则和响应规则是在同一个链上,因此,请求规则中的异常,可以由响应阶段失败函数处理。例如:无论执行请求发生了什么
这篇关于Vue项目总结(4)-API+token处理流程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-10-04package.json 文件位置在哪?-icode9专业技术文章分享
- 2024-10-01Craco.js学习:从入门到实践指南
- 2024-10-01Create-React-App学习:入门与实践指南
- 2024-10-01CSS-in-JS学习:从入门到实践指南
- 2024-09-30JSX语法学习:从入门到初步掌握
- 2024-09-30Mock.js学习:入门教程与实战演练
- 2024-09-30React Hooks学习:从入门到实践
- 2024-09-30受控组件学习:React中的基础入门教程
- 2024-09-29JS定时器教程:初学者必看指南
- 2024-09-29JS对象教程:初学者的全面指南