zoukankan      html  css  js  c++  java
  • axios拦截器

    页面发送http请求,很多情况我们要对请求和其响应进行特定的处理;如果请求数非常多,单独对每一个请求进行处理会变得非常麻烦,程序的优雅性也会大打折扣。好在强大的axios为开发者提供了这样一个API:拦截器。拦截器分为 请求(request)拦截器和 响应(response)拦截器。

    axios拦截器简单介绍

    请求拦截器

    1 axios.interceptors.request.use(function (config) {
    2     // 在发起请求请做一些业务处理
    3     return config;
    4   }, function (error) {
    5     // 对请求失败做处理
    6     return Promise.reject(error);
    7   });

    响应拦截器

    1 axios.interceptors.response.use(function (response) {
    2     // 对响应数据做处理
    3     return response;
    4   }, function (error) {
    5     // 对响应错误做处理
    6     return Promise.reject(error);
    7   });

    vue添加axios拦截器

    安装 axios

    npm install axios –save-dev

    新建文件 axios.js

    开始统一封装axios, 首先引入axios、qs依赖

     1 import axios from "axios"; 2 import qs from "qs"; 

    然后创建一个axios实例,这个process.env.BASE_URL在config/dev.evn.js、prod.evn.js里面进行配置:

    1 /****** 创建axios实例 ******/
    2 const service = axios.create({
    3     baseURL: process.env.BASE_URL,  // api的base_url
    4     timeout: 5000  // 请求超时时间
    5 });

    使用request拦截器对axios请求配置做统一处理

     1 service.interceptors.request.use(config => {    
     2     app.$vux.loading.show({        
     3         text: '数据加载中……'    
     4     });     
     5     config.method === 'post'        
     6         ? config.data = qs.stringify({...config.data})        
     7         : config.params = {...config.params};    
     8     config.headers['Content-Type'] = 'application/x-www-form-urlencoded';     
     9     return config;
    10     }, error => {  //请求错误处理   
    11         app.$vux.toast.show({        
    12             type: 'warn',        
    13             text: error   
    14         });    
    15         Promise.reject(error)
    16     }
    17 );

    对response做统一处理

     1 service.interceptors.response.use(    
     2     response => {  //成功请求到数据        
     3         app.$vux.loading.hide();        
     4         //这里根据后端提供的数据进行对应的处理        
     5         if (response.data.result === 'TRUE') {            
     6             return response.data;        
     7         } else {            
     8             app.$vux.toast.show({  
     9                 //常规错误处理                
    10                 type: 'warn',                
    11                 text: response.data.data.msg            
    12             });        
    13         }    
    14     },    
    15     error => {  //响应错误处理console.log('error');        
    16         console.log(error);        
    17         console.log(JSON.stringify(error));         
    18         let text = JSON.parse(JSON.stringify(error)).response.status === 404            
    19             ? '404'            
    20             : '网络异常,请重试';        
    21         app.$vux.toast.show({            
    22             type: 'warn',            
    23             text: text        
    24         });         
    25         return Promise.reject(error)   
    26     }
    27 )

    将axios实例暴露出去

    1 export default service;

    这样一个简单的拦截器就完成了

    在main.js中进行引用,并配置一个别名($ajax)来进行调用

    1 import axios from 'axios'
    2 import '../axios.js'    //axios.js的路径
    3 
    4 Vue.prototype.$ajax = axios

    应用:一个简单的登录接口

     1 this.$ajax({
     2   method: 'post',
     3   url: '/login',
     4   data: {
     5     'userName': 'haha',
     6     'password': '123456'
     7   }
     8 }).then(res => {
     9   console.log(res)
    10 })

    使用场景

    eg: axios拦截器对路由进行拦截

    1.路由拦截

    在定义路由的时候就需要多添加一个自定义字段requireAuth,用于判断该路由的访问是否需要登录。如果用户已经登录,则顺利进入路由,否则就进入登录页面。

     1 const routes = [
     2     {
     3         path: '/',
     4         name: '/',
     5         component: Index
     6     },
     7     {
     8         path: '/repository',
     9         name: 'repository',
    10         meta: {
    11             requireAuth: true,  // 添加该字段,表示进入这个路由是需要登录的
    12         },
    13         component: Repository
    14     },
    15     {
    16         path: '/login',
    17         name: 'login',
    18         component: Login
    19     }
    20 ];

    定义完路由后,我们主要是利用vue-router提供的钩子函数beforeEach()对路由进行判断。

     1 router.beforeEach((to, from, next) => {
     2     if (to.meta.requireAuth) {  // 判断该路由是否需要登录权限
     3         if (token) {  // 判断当前的token是否存在
     4             next();
     5         }
     6         else {
     7             next({
     8                 path: '/login',
     9                 query: {redirect: to.fullPath}  // 将跳转的路由path作为参数,登录成功后跳转到该路由
    10             })
    11         }
    12     }
    13     else {
    14         next();
    15     }
    16 })

    to.meta中是我们自定义的数据,其中就包括我们刚刚定义的requireAuth字段
    通过这个字段来判断该路由是否需要登录权限
    需要的话,同时当前应用不存在token,则跳转到登录页面,进行登录。登录成功后跳转到目标路由。

    这种方式只是简单的前端路由控制,并不能阻止用户访问,假设有一种情况:当前token失效了,但是token依然保存在本地。这时候你去访问需要登录权限的路由时,实际上应该让用户重新登录。这时候就需要结合 http 拦截器 + 后端接口返回的http 状态码来判断。

    2.拦截器

    要想统一处理所有http请求和响应,就得用上 axios 的拦截器。通过配置http response inteceptor,当后端接口返回401 Unauthorized(未授权),让用户重新登录。

     1 // http request 拦截器
     2 axios.interceptors.request.use(
     3     config => {
     4         if (stoken) {  // 判断是否存在token,如果存在的话,则每个http header都加上token
     5             config.headers.Authorization = `token ${store.state.token}`;
     6         }
     7         return config;
     8     },
     9     err => {
    10         return Promise.reject(err);
    11     });
    12 
    13 // http response 拦截器
    14 axios.interceptors.response.use(
    15     response => {
    16         return response;
    17     },
    18     error => {
    19         if (error.response) {
    20             switch (error.response.status) {
    21                 case 401:
    22                     // 返回 401 清除token信息并跳转到登录页面
    23                     
    24                     router.replace({
    25                         path: 'login',
    26                         query: {redirect: router.currentRoute.fullPath}
    27                     })
    28             }
    29         }
    30         return Promise.reject(error.response.data)   // 返回接口返回的错误信息
    31     });

    链接:https://hupeip.github.io/2018/10/08/axios%E6%8B%A6%E6%88%AA%E5%99%A8/
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 相关阅读:
    用java开发图形界面项目,如何实现从本地选择图片文件并以二进制流的形式保存到MySQL数据库,并重新现实到面板
    算法练习LeetCode初级算法之数组
    算法练习LeetCode初级算法之字符串
    算法练习LeetCode初级算法之排序和搜索
    20169221 201620172 《网络攻防实践》第四周学习总结
    20169221 201620172 《网络攻防》 第三周学习总结
    20169221 201620172 《移动平台应用开发》 第二周学习总结
    20169221 201620172 《移动平台开发时间》 第一周学习总结
    20169221 201620172 《网络攻防实践》 第二周学习总结
    20169221 201620172 《移动平台开发时间》 第三周学习总结
  • 原文地址:https://www.cnblogs.com/hdn420/p/12034786.html
Copyright © 2011-2022 走看看