vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > Vue之Axios拦截器

Vue之Axios拦截器使用及说明

作者:时间sk

这篇文章主要介绍了Vue之Axios拦截器使用及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

在实际开发中有时需要统一处理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:请求拦截器是如何被调用的

(如 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 对象:

三层配置

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);
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文