vue2中使用axios,以及axios拦截器的配置
Posted 。Idea
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue2中使用axios,以及axios拦截器的配置相关的知识,希望对你有一定的参考价值。
目录
1、axios:是一个基于Promise的网络请求库。既可以在node.js(服务器端)使用,也可以在浏览器端使用
B、在项目的main.js文件中导入axios,将其写入Vue的原型中(推荐使用)
C、将axios单独封装到某个配置文件中(在配置文件中单独封装axios实例)—— (推荐使用)
(2)响应拦截器:对服务器端响应给客户端的数据统一进行处理之后再发给客户端
一、vue2项目中如何实现异步请求
1、axios:是一个基于Promise的网络请求库。既可以在node.js(服务器端)使用,也可以在浏览器端使用
(1)在node.js中使用的原生的http模块
(2)在浏览器中使用的XMLHttpRequest
2、vue中的使用方法
(1)安装:npm install axios
(2)引用方法:
A、原生的方式(不推荐使用)
axios(
url: 'http://localhost:8089/students/test', //远程服务器的url
method: 'get' //请求方式
).then(res=>
this.students = res.data
).catch(e=>
console.log(e)
)
//缺点:每个使用axios的组件都需要导入
强调:axios对服务器端数据的封装
res.config:响应信息的配置情况
res.data:响应的数据
res.headers:响应头信息(信息的大小、信息的类型)
res.request:异步的请求对象(XMLHttpRequest)
res.status:请求-响应的状态码(200)
res.statusText:请求-响应状态码对应的文本信息
B、在项目的main.js文件中导入axios,将其写入Vue的原型中(推荐使用)
//该文件是脚手架项目中的main.js
import axios from "axios";
Vue.prototype.$http = axios //在Vue的原型上添加一个$http属性,该属性保存了axios
axios.defaults.baseURL = 'http://localhost:8089'
在组件中通过this.$http的方式来使用
this.$http.get('http://localhost:8089/students/test').then(res=>
this.students = res.data
).catch(e=>
console.log(e)
)
缺点:只能在vue2中使用,vue3中不能用
C、将axios单独封装到某个配置文件中(在配置文件中单独封装axios实例)—— (推荐使用)
在\\src\\assets静态资源文件夹下创建axios配置文件
//配置文件:axiosapi.js
import axios from "axios";
const axiosapi = axios.create(
baseURL: 'http://localhost:3000', //基础的服务器地址
timeout: 5000 //连接超时的时间(单位是毫秒)
)
export default axiosapi //axiosapi是axios的实例
在组件中使用如下:
import $http from '../config/axiosapi' //$http是在导入时自定义的命名可变的
$http.get('/students/test').then(res=>
this.students = res.data
).catch(e=>
console.log(e)
)
优点:既可以在Vue2中使用,也可以在Vue3中使用
3、axios中不同请求方式向服务器提交数据的格式:
(1)get方式请求:服务器端通过 req.query.参数名 来接收
第一种:直接将请求参数绑在url地址上。
第二种:通过params方式进行提交
(2)post方式请求:服务器端通过 req.body.参数名 来接收
(3)put方式请求:和post方式一样 // 传参的方式
(4)delete方式请求:和get方式一样 // 传参的方式
二、axios拦截器的配置
1、axios模块的作用:是对基于http请求的封装。在浏览器对异步请求对象XMLHttpRequest进行封装
2、拦截器:
(1)请求拦截器:对客户端发起的请求进行统一的前期处理
(token、时间戳、cookie等)
(2)响应拦截器:对服务器端响应给客户端的数据统一进行处理之后再发给客户端
axios配置文件如下:
import axios from "axios";
//1. 创建axios实例,配置基础路径
const axiosapi = axios.create(
baseURL:'http://localhost:3000',
timeout:5000,//连接超时
);
//2. 定义请求拦截器:给所有请求都带上token
axiosapi.interceptors.request.use((req)=>
let token = sessionStorage.getItem('Auth');//获取页面存储的token
if (token)
req.headers['Auth'] = token;//将token添加至请求头对象的Auth属性中
return req;
,(error)=>//返回错误的信息
return Promise.reject(error);
);
//3. 定义响应拦截器: 对服务器响应客户端的数据进行统一处理
axiosapi.interceptors.response.use(res=>
//3.1 对响应数据进行处理
let data = res.data;
let code = data.code;
if(code === 200)
//请求成功时,将res.data对象返回给响应对象
return data;
else
return Promise.reject(data);
,(error)=>
return Promise.reject(error);
)
//4. 导出axios实例,供组件异步请求使用
export default axiosapi;
vue中axios请求拦截器和响应拦截器 以及401状态处理
一、axios
在vue中啊 我们不需要去用原生XHR去发 ajax ,因为啊 原生js写起来比较繁琐,并不易我们去开发, 我们可以通过axios 去发ajax?看到axios不要觉得新词就很陌生
官网: axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范,有以下特点:
- 从浏览器中创建 XMLHttpRequests
- 从 node.js 创建 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换 JSON 数据
- 客户端支持防御 XSRF
复习 axios二次封装 跳转链接
二、请求拦截器
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
先知道请求拦截器啊并不是说对请求进行了拦截不让去请求 ,其实目的是在发送请求前进行操作,比如啊 我们在请求头添加token,我们在请求拦截器中添加啊,所有的请求都会经过请求拦截器,是不是不用我们手动挨个去加了,这也是最常用的使用场景了
// 请求拦截器1
instance.interceptors.request.use(function (config) {
config.header.xxxx1 = 1000
return config
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error)
})
// 请求拦截器2
instance.interceptors.request.use(function (config) {
config.header.xxxx2 = 'abc'
return config
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error)
})
发送请求中 请求头中除了添加token 也可以添加其他的 上面的代码只是例子,添加后并无作用
案例 请求头(headers)中携带token例子:
import axios from 'axios' //引入 axios
import store from '../store/index' //vuex数据
import router from '../router/auth' // 路由
export const request1 = axios.create({ //创建一个axios实例
baseURL: 'http://localhost:8000'
})
// 添加请求拦截器
request1.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
// console.log(config)
const token = store.state.tokenInfo.token //获取vuex中的token
if (token) {
config.headers.Authorization = `Bearer ${token}` //如果有token 就在请求头上添加token
}
return config
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error)
})
拦截器写在基地址哦 上面引入一些模块和包 为了更好理解 注意token是在vuex里获取的 也可以通过localStorage中进行获取哦 回顾知识点token持久化
三、响应拦截器
所有从后端响应回来的数据都会进入响应拦截器里 ,我们可以在响应拦截器里去进行操作,通常判断token失效
基本写法
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
案例 401问题
1. 什么时候出现401 ? token过期在进行用户操作,token一般都会有时间限制,比如十二小时后token过期 过期后的token再去权限操作就会报出401错误
2.模拟token失效 对于token失效我们不能干等12小时 这也太漫长了,但是我们可以模拟token失效 通过修改vuex 里的token 因为vuex中的token是响应式的 我们只需要对齐进行修改,注意不要刷新!!(刷新后token又重新获取了)
模拟token失效 在vuex中 删除token中的几个字符就可以模拟token失效 , 因为我下次操作肯定 还会发请求 下次带着错误的token和失效一个道理
3. refresh_token 我们在图中看到了refresh_token(这也是后端提供给我们的,保存在了vuex里,接下来讲他是起到什么作用)
(1) 如果token失效后 例如失效期是一小时 用户发现突然操作没有权限了 只能去重新登录 重新获取token 这是对用户非常不好的体验,每次一小时都要重新登录一次,用户骂骂咧咧的删除了网页
(2) 所以啊 这时候refresh_token的作用来了,它的作用呢也可以作为用户的令牌,token失效后,我们可以通过refresh_token去重新获取token 当然这些操作都是报了401错误在响应拦截器里操作的,对于refresh_token可以通过响应拦截器做到 用户无感的体验 让用户感觉不到任何 操作,但是背后的程序员付出了很多, 哎 果然用户体验的背后都有一个伟大的程序员, 当然他也是有时间限制的 一般为7天/14天当然也是后端设置的
(3)这里啊有个疑问 为什么不能直接设置14天 或者永久呢 搞这么麻烦? 个人理解的是 如果token呢一直一样 那也就失去了保留token 的意义所在,那我还要token干嘛,所以呢第一点 是保证token不被盗取,能够保证用户的安全性更高,第二点也差不多,因为refresh_token是去请求后端的,这也是请求后能告诉后台用户在连接,能够得到响应。(希望大家看到能补充一最好)
4. 接下来先看一张具体的流程图(有 · 复杂哦,仔细看)
具体步骤
对于某次请求A,如果是401错误 (2)
- 有refresh_token,用refresh_token去请求回新的token (3)
- 新token请求成功 (4)
- 更新本地token (5)
- 再发一次请求A (6)
- 新token请求失败
- 携带请求地址,跳转到登陆页
- 没有refresh_token,说明没有登陆
- 携带请求地址,跳转到登陆页
转换为代码 为了更好理解 把每一句的注释写在后面 (仔细看很好理解,别觉得多一扫而过)
import store from '../store/index'
import router from '../router/auth'
request1.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response
}, async function (error) {
// 对响应错误做点什么
console.dir(error)
const refreshToken = store.state.tokenInfo.refresh_token // 拿到refres_token 定义变量不能和引入的变量名重复 例如 const store
if (error.response.status === 401) { // 在error对象中 可以看到状态 是否为401
if (refreshToken) {
// 1. token 过期的情况 判断如果有refreshToken 去发ajax
try {
const res = await axios({
url: 'http://localhost:8000/v1_0/authorizations',
method: 'PUT',
headers: { // headers 不能按接口文档抄 H不能大写!!!!
Authorization: `Bearer ${refreshToken}`
}
})
const newToken = res.data.data.token // 拿到新的token再去发请求
console.log(newToken)
// 发请求调用vuex的mutations
store.commit('setTokenInfo', { token: newToken, refresh_token: refreshToken }) // 这里的token 和 refresh_token要和之前定义变量匹配(vuex中)
return request1(error.config) // 哪里发请求就在哪调用 这里指的是只是修改了新的token 并没有修改error其他的值 只是重新发请求
} catch (error) {
// 2. refreshToken 也过期了 但是登录着呢 但是之前的已经登录已经跳不过去了 所以要设置为空 (这里之前设置过登录用户无法访问登录页 )
store.commit('setTokenInfo', {}) // 传一个空的token就可以了
// encodeURIComponent 因为我们在路由传参的时候遇见&符后面的参数不能转码 所以我们要把整句转换成编码形式
// 下面代码解释 例如我从文章页进行操作 没有token自动跳到登录页 登录之后用户想的是继续访问文章页 并不是想访问主页 所以我们就要保存刚才的路径
// 通过'login?参数='+刚才的路径地址 这样登录页面就能拿到参数 登陆成功后进行跳转 this.$router.push(this.$route.query.returnUrl || '/')
router.push('/login?returnUrl=' + encodeURIComponent(router.currentRoute.fullPath)) // router.currentRoute 相当于 vue中的$route
return Promise.reject(new Error('refresh_token清空')) // 抛出错误不然会可能提示执行成功
}
} else { // 3. 如果没有refresh_token 去登录 和上面同样的操作
console.log('未获取到refreshToken,所以要去登录')
store.commit('setTokenInfo', {})
router.push('/login?returnUrl=' + encodeURIComponent(router.currentRoute.fullPath)) // router.currentRoute 相当于 vue中的$route
return Promise.reject(new Error('refresh_token不存在'))
}
}
})
挪出一部分作为笔记哈 也是常见不会写或者错误
1. router.currentRoute 相当于 vue中的$route
2. headers: { // headers 不能按接口文档抄 H不能大写!!!!
Authorization: `Bearer ${refreshToken}`
}3. store.commit('setTokenInfo', { token: newToken, refresh_token: refreshToken }) // 这里的token 和 refresh_token要和之前定义变量匹配(vuex中)
4. encodeURIComponent 因为我们在路由传参的时候遇见&符后面的参数不能转码 所以我们要把整句转换成编码形式
// 下面代码解释 例如我从文章页进行操作 没有token自动跳到登录页 登录之后用户想的是继续访问文章页 并不是想访问主页 所以我们就要保存刚才的路径
// 通过'login?参数='+刚才的路径地址 这样登录页面就能拿到参数 登陆成功后进行跳转 this.$router.push(this.$route.query.returnUrl || '/')
router.push('/login?returnUrl=' + encodeURIComponent(router.currentRoute.fullPath)) // router.currentRoute 相当于 vue中的$route
5. return request1(error.config) // 哪里发请求就在哪调用 这里指的是只是修改了新的token
有了上面的操作 啊 token失效后 又去拿refresh_token又去请求了一遍 ,最后请求过来的数据拿到最新的token ,再去保存到vuex中,然后再去进行操作 return request1(error.config) 这句话不要以为error就是表示错误信息,它里面其他的信息没变,我们只是重新获取了token ,重新发了一遍请求,当然是哪里调用就在哪里重新请求,最主要的一句就是 让用户无感!!!!!
以上是关于vue2中使用axios,以及axios拦截器的配置的主要内容,如果未能解决你的问题,请参考以下文章