- A+
一、一体化运营平台前端请求部分
1.接口封装
一体化运营平台采用的是封装axios的方式来简化请求接口的使用,在添加新接口时只要调用封装好的方法就可以发出请求并直接得到解析后的数据
2.整个过程解析
(1)请求方法调用request方法并传需要的参数
sync_collect_diff_data(data) { return request({ url: '/resource-server/collection/sync_collect_diff_data', //请求路径 method: 'post',//请求方式,这里是后面自己设置的,不是常规意义上的get/post Data //请求参数 }) }
(2)request方法进入到until目录下的request.js方法类
// create an axios instance const service = axios.create({ baseURL: process.env.BASE_API, // api 的 base_url timeout: 60000 // request timeout })
创建一个axios实例,其中baseURL是配置在其它文件中,主要用来区分开发环境和测试环境等
(3)给axios实例设置请求头
axios.interceptors.request.use(config => { if (sessionStorage.getItem('accessToken')) { config.headers.accessToken = sessionStorage.getItem('accessToken') } if (sessionStorage.getItem('clientId')) { config.headers.clientId = sessionStorage.getItem('clientId') } if (sessionStorage.getItem('csrfToken')) { config.headers.csrfToken = sessionStorage.getItem('csrfToken') } if (sessionStorage.getItem('loginName')) { config.headers.loginName = sessionStorage.getItem('loginName') } return config });
请求发起时会附带上在这里面设置的参数,表现形式为以下
(4)设置接收方法
axios.interceptors.response.use((response) => { if (response.data.errCode === 990014) { router.push('/') } ... }
接收方法中可以设置对接受到的response数据进行加工解析,以及错误处理,在这个过程中可以和后端约定几种通用的处理方式,例如在检测到登录信息缺失等时自动弹出到登录界面
(5)抛出特定类型的接收数据解析方法
get(url, params = {}) { return new Promise((resolve, reject) => { axios.get(process.env.API_ROOT + url, { params }).then(res => { if (res) { if (res.data.errCode === 0) { resolve(res.data.data); } else { reject(res.data.errMsg); } } }).catch(error => { reject(error); }) }) },
此类型方法需要通过export来抛出,同时方法名就是之前调用request方法时候的类型,
在此方法中resolve代表成功的情况,此时方法会将数据返回给调用方,reject方法则代表失败的情况下返回的数据,需要注意的一点是方法返回无论成功还是失败,是先经过上面设定的拦截器,所以如果上面拦截器处理之后,就不会到这边方法的处理流程中
二、Axios知识学习
一、axios的封装
在vue项目中,和后台交互获取数据这块,我们通常使用的是axios库,它是基于promise的http库,可运行在浏览器端和node.js中。他有很多优秀的特性,例如拦截请求和响应、取消请求、转换json、客户端防御XSRF等。
1.安装导入
npm install axios; // 安装axios
一般会在项目的src目录中,新建一个request文件夹,然后在里面新建一个http.js和一个api.js文件。http.js文件用来封装我们的axios,api.js用来统一管理我们的接口。
// 在http.js中引入axios import axios from 'axios'; // 引入axios import QS from 'qs'; // 引入qs模块,用来序列化post类型的数据,后面会提到
2.环境的切换
通过node的环境变量来匹配我们的默认的接口url前缀。axios.defaults.baseURL可以设置axios的默认请求地址
// 环境的切换 if (process.env.NODE_ENV == 'development') { axios.defaults.baseURL = 'https://www.baidu.com';} else if (process.env.NODE_ENV == 'debug') { axios.defaults.baseURL = 'https://www.ceshi.com'; } else if (process.env.NODE_ENV == 'production') { axios.defaults.baseURL = 'https://www.production.com'; }
在一体化中是通过分文件抛出的方式
3.设置请求超时
通过axios.defaults.timeout设置默认的请求超时时间。例如超过了10s,就会告知用户当前请求超时,请刷新等。
axios.defaults.timeout = 10000;
4.post请求头的设置
post请求的时候,我们需要加上一个请求头,所以可以在这里进行一个默认的设置,即设置post的请求头为
application/x-www-form-urlencoded;charset=UTF-8
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
5.请求拦截
我们在发送请求前可以进行一个请求的拦截,为什么要拦截呢,我们拦截请求是用来做什么的呢?比如,有些请求是需要用户登录之后才能访问的,或者post请求的时候,我们需要序列化我们提交的数据。这时候,我们可以在请求被发送之前进行一个拦截,从而进行我们想要的操作。一体化中使用这块设定了权限校验,也就是crftoken等
// 先导入vuex,因为我们要使用到里面的状态对象 // vuex的路径根据自己的路径去写 import store from '@/store/index'; // 请求拦截器axios.interceptors.request.use( config => { // 每次发送请求之前判断vuex中是否存在token // 如果存在,则统一在http请求的header都加上token,这样后台根据token判断你的登录情况 // 即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断 const token = store.state.token; token && (config.headers.Authorization = token); return config; }, error => { return Promise.error(error); })
这里说一下token,一般是在登录完成之后,将用户的token通过localStorage或者cookie存在本地,然后用户每次在进入页面的时候(即在main.js中),会首先从本地存储中读取token,如果token存在说明用户已经登陆过,则更新vuex中的token状态。然后,在每次请求接口的时候,都会在请求的header中携带token,后台人员就可以根据你携带的token来判断你的登录是否过期,如果没有携带,则说明没有登录过。
响应拦截器很好理解,就是服务器返回给我们的数据,我们在拿到之前可以对他进行一些处理。例如上面的思想:如果后台返回的状态码是200,则正常返回数据,否则的根据错误的状态码类型进行一些我们需要的错误,其实这里主要就是进行了错误的统一处理和没登录或登录过期后调整登录页的一个操作。
6.封装get方法和post方法
我们常用的ajax请求方法有get、post、put等方法,相信小伙伴都不会陌生。axios对应的也有很多类似的方法,不清楚的可以看下文档。但是为了简化我们的代码,我们还是要对其进行一个简单的封装。下面我们主要封装两个方法:get和post。
get方法:我们通过定义一个get函数,get函数有两个参数,第一个参数表示我们要请求的url地址,第二个参数是我们要携带的请求参数。get函数返回一个promise对象,当axios其请求成功时resolve服务器返回 值,请求失败时reject错误值。最后通过export抛出get函数。
post方法:原理同get基本一样,但是要注意的是,post方法必须要使用对提交从参数对象进行序列化的操作,所以这里我们通过node的qs模块来序列化我们的参数。这个很重要,如果没有序列化操作,后台是拿不到你提交的数据的。
这里有个小细节说下,axios.get()方法和axios.post()在提交数据时参数的书写方式还是有区别的。区别就是,get的第二个参数是一个{},然后这个对象的params属性值是一个参数对象的。而post的第二个参数就是一个参数对象。两者略微的区别要留意
7.封装配置的优点
1.通过直接引入我们封装好的axios实例,然后定义接口、调用axios实例并返回,可以更灵活的使用axios,比如你可以对post请求时提交的数据进行一个qs序列化的处理等。
2.请求的配置更灵活,你可以针对某个需求进行一个不同的配置。关于配置的优先级,axios文档说的很清楚,这个顺序是:在 lib/defaults.js 找到的库的默认值,然后是实例的 defaults 属性,最后是请求的 config 参数。后者将优先于前者。
3.restful风格的接口,也可以通过这种方式灵活的设置api接口地址。
三、一体化后端请求部分
1.后端流程
登录过程中后端会生成accessToken和clientId用来进行权限校验工作,也就是之前写到的在请求头中设定这两项的目的,如果是被标记为需要权限校验的接口,则会校验第三项,也就是csrfToken。根据校验结果来决定是否调用实际方法,如果是不需要校验的接口则会直接进入实际方法
2.后端请求封装
后端响应请求时也进行了部分封装,主要体现在路由,权限校验
(1)路由:一体化在系统相关后端上是采用的分模块部署的,具有一个统一的路由,通过这个统一路由来提供一个统一对外接口,这就导致在请求时存在一个注意事项,与常规spring+mybatis路由不同,还需要加上一层模块名字路由
/resource-server/collection/delete_collect_cfg_data
/模块名/类层级路由/方法级路由
(2)权限校验:权限校验这块采用的时AOP切面,环绕通知的方式来封装实现的,通过在接口上增加一个 @AuthPlugin来开启权限校验,权限校验流程简单来说分问两个层级,第一级校验是否是有效用户,这块采用的是ceftoken比对来确认,第二层则是确认是否有权限访问当前接口,这块则是读表的方式来确认
// 只拦截使用了 @AuthPlugin 注解的方法 AuthPlugin authPlugin = method.getAnnotation(AuthPlugin.class); if (authPlugin == null) { return joinPoint.proceed(); }
@AuthPlugin(serviceCode = "model-cancel", logLevel = LogRecordLevel.NO_NEED)
参数意义:服务名,这个需要和给用户配置的服务权限一致;日志级别,权限校验同时集成了日志输出功能,所以需要区分日志级别