Vue之Axios拦截器使用及说明
作者:时间sk
在实际开发中有时需要统一处理HTTP的请求和响应,会在请求或响应被 then 或 catch 处理前拦截它们。
比如会员登录安全验证,这时使用拦截器可以很轻松的实现,先看一下拦截器的语法形式代码如下:
// 添加请求拦截器
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);
});
HTTP请求和响应拦截器是一种在HTTP请求发送之前和响应接收之后,对请求和响应进行统一处理的方式。
通过拦截器,可以在不修改每个请求处理逻辑的情况下,对所有HTTP请求和响应进行统一的处理。
在Axios中,可以通过axios.interceptors.request和axios.interceptors.response来添加请求和响应拦截器。
拦截器允许我们在请求发送前修改请求配置,或者在响应接收后修改响应数据,也可以在请求或响应出错时进行处理。
1.请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
这个拦截器会在每次HTTP请求发送之前被调用,可以修改请求的配置(如添加请求头、修改请求参数等)。
如果发生错误,可以在这里进行处理,并返回一个被拒绝的Promise。
2.响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
这个拦截器会在每次HTTP响应接收后被调用,可以修改响应数据,或者在响应出错时进行处理。
例如,可以统一处理401未认证错误,跳转到登录页面。
3.在实际开发中有时需要统一处理HTTP的请求和响应,这句该如何理解?
我的理解是,统一处理HTTP请求和响应意味着在整个应用中,对所有的HTTP请求和响应进行一致的处理,而不需要在每个请求的地方重复相同的逻辑。
例如,可以在请求拦截器中添加统一的认证头,或者在响应拦截器中统一处理错误状态码。
拦截器一定要封装我在utils文件下建立一个http.js文件
http.js文件
import Axios from "axios";
import _config from "../conf/confg"; //引入baseAPI
import qs from "qs";
//导出名叫request_name的一个方法
export function request_name(config1 = {})
{//创建实例
let service = Axios.create({ baseURL: _config.baseApi });
return service.request(config1);
}
main.js文件
import Vue from "vue";
//将request_name方法挂载到全局上
import { request_name } from "./assets/js/utils/http";
Vue.prototype.$requestname = request_name;
new Vue({
router,
store, //注册store
render: (h) => h(App),
}).$mount("#app");
做登录验证
login.vue
<template>
<div>
用户名:<input type="text" v-model="uname" /> <br />
密码:<input type="password" v-model="upassword" />
<button type="button" @click="submit()">提交</button>
</div>
</template>
<script>
export default{
name :"user-name",
data(){
return{
uname:"",
upassword:""
}
},
methods:{
submit(){
if(this.uname==""){alert("请输入姓名"); return;}
if(this.upassword==""){ alert("请输入密码"); return;}
this.$requestname({
url:"/home/user/pwdlogin?token="+this.$config.token,
method:"post",
data:{cellphone:this.uname,password:this.upassword}
//使用request_name函数返回的结果
}).then( res=>{console.log(res),
localStorage['uname']=res.data.nickname;
localStorage['uid']=res.data.uid;
localStorage['authToken']=res.data.auth_token;
localStorage['isLogin']=true;
this.$router.replace("/")
} )
}
}
}
</script>
由于这里的post数据要类型转换,所以我们可以在请求拦截器中,完成数据类型转换
data:{cellphone:this.uname,password:this.upassword}
http.js文件
import Axios from "axios";
import _config from "../conf/confg";
import qs from "qs"; //这里的post数据类型转换我们用拦截器来做
//导出名叫request_name的一个方法
export function request_name(config1 = {} ) {
//创建实例
let service = Axios.create({ baseURL: _config.baseApi });
//请求拦截器来做post数据转换
service.interceptors.request.use( (config) => {
console.log(config);// 拦截器修改逻辑“这里是打印”
return config;//将修改后的配置项返回
}, (error) => {
return Promise.reject(error);
})
return service.request(config1)
}
问题1:请求拦截器是如何被调用的
- 1.创建了一个独立的 Axios 实例 service,并配置了 baseURL
- 2. 注册动作:通过 interceptors.request.use 将拦截器函数挂载到 Axios 实例上。
- 3. 此时拦截器并未执行,只是完成注册。
- 4. 当调用 request_name 方法时,实际执行的是 service.request(config1)。
- 5. 此时 Axios 内部会自动触发已注册的拦截器。
- 6. 这里的拦截器中的动作是打印 config对象console.log(config)
- 7. 拦截器是自动触发的,只要通过 service.request() 或快捷方法
(如 service.get()、service.post())发起请求,所有注册的拦截器会自动执行。
只要通过 service.request() 或快捷方法(如 service.get()、service.post())发起请求,所有注册的拦截器会自动执行。
问题2: service.interceptors.request.use( (config) => { }中的config完全来自service.request(config1)中的config1吗?
拦截器中的 config 参数本质来源于你调用 service.request(config1) 时传入的 config1 ,但并非直接等同于 config1。Axios 在内部对配置进行了 多层合并处理,最终传递给拦截器的 config 是合并后的完整配置对象。
以下是详细流程分析:
一、config 的生成过程
当调用 service.request(config1) 时,Axios 会通过以下步骤生成最终的 config 对象:
三层配置
- 1.Axios 全局默认配置:包括 headers 的默认值(如 Accept 和 Content-Type)。
- 2.实例级默认配置:通过 Axios.create({ baseURL: ... }) 设置的配置(如 baseURL)。
- 3. 请求级配置:调用 service.request(config1) 时传入的 config1。
Axios 会将这三层配置合并,形成最终的 config 对象,传递给拦截器。config对象包含完整的请求信息:如 url、method、data、headers、timeout 等。

import Axios from "axios";
import _config from "../conf/confg";
import qs from "qs"; //这里的post数据类型转换我们用拦截器来做
//导出名叫request_name的一个方法
export function request_name(config1 = {} ) {
//创建实例
let service = Axios.create({ baseURL: _config.baseApi });
//请求拦截器来做post数据转换
service.interceptors.request.use( (config) => {
console.log(config);// 拦截器修改逻辑“这里是打印”
if (config.method.toLocaleLowerCase() === "post")
{ config.data = qs.stringify(config.data);}
return config;//将修改后的配置项返回
}, (error) => { return Promise.reject(error); })
return service.request(config1).then((res) => res.data);
}
return service.request(config1).then((res) => res.data);请求成功后,把响应结果,由res接收,提取响应数据 res.data 并返回。
写这一步的目的then((res) => res.data)是为了简化调用数据的步骤



localStorage存储用户信息。这可能是因为需要在多个页面或浏览器会话中保持用户登录状态,而localStorage提供了持久化存储的能力。存储的信息包括昵称、用户ID、认证令牌和登录状态,这些都是维持用户会话的关键数据。
会员登录认证的核心就是:验证我们localStorage本地缓存的token,跟我服务器上的token值是否一致,如果一致则算你登录成功,如果不一致则登录失败,要跳到登录页面去
<template>
<div>
欢迎{{name1}}回来<br />{{message}}<br />
<button type="button" @click="outLogin()">安全返回</button>
</div>
</template>
<script>
export default{
name:"person-name",
data(){
return{name1: localStorage['uname'],
message:""
}
},
---------------------------------------------
安全认证就用它
created(){
this.$requestname({
url:"/home/user/safe?token="+this.$config.token,
method:'post', //将本地数据uid和token拿到服务器做对比
data:{uid:localStorage['uid'],auth_token:localStorage['authToken']}
},this.$riuter).then(res=>{console.log(res)})
},
--------------------------------------------------
methods:{
outLogin(){
//安全退出
this.$requestname({
url:"/home/user/safeout?token="+this.$config.token,
method:"post",
data:{uid:localStorage["uid"]}
}).then( res=>{console.log(res)
if(res.code==200){
localStorage.removeItem("unname") ;
localStorage.removeItem("isLogin") ;
localStorage.clear();//清除所有本地缓存
this.$router.replace("/login");
}
} )
}
},
}
</script>

有权限访问说明:将本地数据uid和token跟服务器接口的数据一致,也同时说明,登录成功

安全退出:清除本地缓存

import Axios from "axios";
import _config from "../conf/confg";
import qs from "qs"; //这里的post数据类型转换我们用拦截器来做
//导出名叫request_name的一个方法
export function request_name(config1 = {}, router) {
//创建实例
let service = Axios.create({ baseURL: _config.baseApi });
//-------------------------------------------------------------------------------
//请求拦截器来做post数据转换
service.interceptors.request.use(
(config) => {
console.log(config);
if (config.method.toLocaleLowerCase() === "post") {
config.data = qs.stringify(config.data);
} else if (config.method.toLocaleLowerCase() === "file") {
config.method = "post";
let formData = new FormData();
if (config.data instanceof Object) {
for (let key in config) {
formData.append(key, config.data[key]);
}
config.data = formData;
}
// config.method = "post";
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
//--------------------------------------------------------------
//响应拦截器
service.interceptors.response.use(
(response) => {
console.log(response); //判断是否调用了会员安全认证接口了
if (response.config.url == "/home/user/safe?token=1ec949a15fb709370f") {
if (response.data.code != 200) {
//没有调用了会员安全认证接口,即登录验证失败
localStorage.clear();//清除缓存
router.replace("/login");
//跳到登录页面(这里的路由是从request_name中传进来的)
}
}
return response;
},
(error) => {
return Promise.reject(error);
}
);
//------------------------------------------------------------------------------
return service.request(config1).then((res) => res.data);
}
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
