Axios 网络请求组件封装 (鉴权、刷新、拦截)

一、前言

注意:本教程需要你对axios有一定的了解,不适用于小白(只能借鉴,希望你能自己动手),注释都写的很清楚。此封装并非完整版,已进行部分删减修改操作,但仍然适用于大部分业务场景,如果不适用于你项目的特定业务场景,请自行修改。


Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

Axios的特性如下:

  • 从浏览器中创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF

二、安装及其使用

安装

使用 npm:

$ npm install axios

使用 bower:

$ bower install axios

使用 cdn:

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

三、开始封装

axios封装 (api.js)

import axios from 'axios'                       //网络请求组件 import Qs from 'qs' //数据解析库(使用JSON亦可,本文未使用QS,如需要,可替换JSON为QS) import { Message } from 'element-ui' //element组件,本文使用message消息提示(可根据自行需要进行替换其他TOAST) import router from '../router' //路由引入,拦截访问,进行路由跳转 import * as api from '../api/commonApi' //封装axios请求组件,在特定业务场景使用里面的请求 import store from '../store/index' //axios网络封装请求开始 var service = axios.create({ // process.env.NODE_ENV获取当前业务场景的环境,以使用不同的api地址。API_ROOT为自定义api请求地址(请自行替换) baseURL: process.env.NODE_ENV === 'production' ? process.env.API_ROOT : process.env.NODE_ENV === 'presentation' ? process.env.API_ROOT : process.env.API_ROOT, timeout: 100000, }) //获取登录时存储的sessionStorage let getToken = window.sessionStorage.getItem('token'); //进行数据格式的转换 let parseToken = JSON.parse(getToken); //拦截网络请求开始 service.interceptors.request.use(config => { // 判断token是否存在,如果存在,就给请求头加上token if (sessionStorage.getItem('token')) { config.headers.Authorization = parseToken.token_type +" "+ parseToken.access_token; } // 检测如果请求为post,进行转换为JSON字符串(一般情况下不需要) if (config.method === 'post') { config.data = JSON.stringify(config.data) } // 设置请求头 // 请求头常见的有以下几种方式,可根据需要自行修改 // ’application/json’,’application/x-www-form-urlencoded’,’multipart/form-data’ // config.headers = { // 'Content-Type':'application/x-www-form-urlencoded' // } return config; },error => { // 请求错误消息提示 Message({ message: error.message, type: "error" }); return Promise.reject(error.data.error.message); }); //返回状态判断(添加响应拦截器) service.interceptors.response.use(response => { return response // 返回数据进行消息提示 if(!response.data){ Message({ message: "数据响应失败", type: "warning" }); } },error => { //获取错误信息 const config = error.config //判断错误信息的url是否为刷新接口的url,process.env.API_ROOT请自行替换为请求地址,如:192.168.1.1 if(config.url === process.env.API_ROOT +"/refreshToken"){ Message({ message: '数据刷新失败,请重新登录再进行操作。', type: 'error', duration: 1.5 * 1000 }) //清除vuex及其sessionStorage等信息 store.commit('remove_login_info') //进行路由跳转 router.push('/login') return } //拦截response 返回状态码,如果为401需要重新进行token刷新,调用请求并传入参数 if (error.response.status === 401) { const refresh = new Promise((resolve, reject) => { api.refreshToken(store.state.usertonken.refresh_token).then((resp) => { if(resp.data.code === 2000000){ this.loginloading = true; //重新添加token到sessionStorage window.sessionStorage.setItem('token',JSON.stringify(resp.data.data)) //用vuex重新设置基本信息 store.commit('add_login_info',resp.data.data) this.loginloading = false; //修改_retry config._retry = true; let getToken = window.sessionStorage.getItem('token'); //进行数据格式的转换 let parseToken = JSON.parse(getToken); //修改原请求的token config.headers.Authorization = parseToken.token_type + " " +parseToken.access_token; config.baseURL = ''; resolve(axios(config)); } }).catch(function (error) { return Promise.reject(error); }); }); return refresh; } //拦截response 返回状态码,如果为400进行错误消息提示 if (error.response.status === 400) { Message({ // message:error.response.data.err_msg, message:'操作失败', type: "warning", duration: 1.5 * 1000 }); } //拦截response 返回状态码,如果为403进行错误消息提示 if (error.response.status === 403) { Message({ message: '暂无权限,请重新登录再进行操作。', type: 'error', duration: 1.5 * 1000 }) //清除vuex及其sessionStorage等信息 store.commit('remove_login_info') //进行路由跳转 this.$router.push({path:'/login'}) } return Promise.reject(error); } ); service.install = (Vue) => { Vue.prototype.$http = axios } export default service 

刷新token的方法


import api from './api'   //引入axios网络请求封装组件 //进行请求方法的封装,并传入请求参数(非必需) //token刷新方法 export function refreshToken(refresh_token){ let data = { refresh_token} return fetch({ url:'refreshToken', method: 'post', data, }) } 

调用方式

import api from './api'

api({ url: '请求地址', method: 'post', data: 请求参数 }).then((resp) => { console.log(resp.data) }) 

后记

此封装纯属个人自用,为了方便大家使用,已进行部分修改和整理。如果你有任何疑问或者建议,欢迎留言进行评论。如果你觉得帮助到了你,请分享给更多的人。感谢你的支持!!!

猜你喜欢

转载自www.cnblogs.com/ceet/p/10020216.html