axios 拦截器

Posted 努力学编程呀(๑•ี_เ•ี๑)

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了axios 拦截器相关的知识,希望对你有一定的参考价值。

学习目标:

axios 拦截器

学习内容:

axios 拦截器


学习笔记:

axios 拦截器

一、什么是axios拦截器、为什么要使用axios拦截器?

在vue项目中,我们通常使用axios与后台进行数据交互,axios是一款基于promise封装的库,可以运行在浏览器端和node环境中。

axios特性:
1、拦截请求和响应
2、取消请求
3、转换json
4、客户端防御XSRF等。

使用拦截器的原因:

若出现请求数多的情况下,我们将会用到 axios 的一个API:拦截器。
页面发送http请求,很多情况我们要对请求和其响应进行特定的处理,
如果每个请求都附带后端返回的token,我们需要在拿到response之前loading动画的展示等。

拦截器的分类:

拦截器分为 请求(request)拦截器响应(response)拦截器

拦截器的使用:
在请求或响应被 then 或 catch 处理前拦截它们。

(1)、请求拦截器

// 添加请求拦截器
axios.interceptors.request.use(
    function (config) 
        do......
        // 在发送请求之前进行操作
        return config;
    ,
    function (error) 
        do......
        // 对请求错误进行操作
        return Promise.reject(error);
    
);

举例:

// http request 拦截器
axios.interceptors.request.use(
    config => 
        if (store.state.token)  
         // 判断是否存在 token, 如果存在的话, 则每个 http header 都加上 token
            config.headers.Authorization = `token $store.state.token`;
        
        return config;
    ,
    err => 
        return Promise.reject(err);
    );

(2)、响应拦截器

// 添加响应拦截器
axios.interceptors.response.use(
    function (response) 
        // 对响应数据进行操作
        return response;
    ,
    function (error) 
        // 对响应错误进行操作
        return Promise.reject(error);
    
);

举例:

// http response 拦截器
axios.interceptors.response.use(
    response => 
        return response;
    ,
    error => 
        if (error.response) 
            switch (error.response.status) 
                case 401:
                    // 返回 401 清除 token 信息并跳转到登录页面
                    store.commit(types.LOGOUT);
                    router.replace(
                        path: 'login',
                        query: redirect: router.currentRoute.fullPath
                    )
            
        
        return Promise.reject(error.response.data)  
         // 返回接口返回的错误信息
    );

说明:
如果我们使用中需要统一处理所有 http 请求和响应, 就需要使用 axios 拦截器。
通过配置 http response inteceptor, 如果后端接口返回 401 Unauthorized(说明该用户未授权), 用户需重新登录。

移除拦截器:

const myInterceptor = axios.interceptors.request.use(function () 
 do ...... 
//具体的操作
);
axios.interceptors.request.eject(myInterceptor);


为自定义 axios 实例添加拦截器:

const instance = axios.create();
instance.interceptors.request.use(function ()  
    do ...... 
   //具体的操作
);

如何在项目中调用 axios 拦截器

1、将axios封装好
2、在项目中直接调用即可
(注:接口统一写在api文件夹中,为了我们后期使用及维护方便,书写是我们最好将不同模块或组件的请求分开写到不同的文件里)。(如果你的业务非常复杂,建议把

举例:

//   示例 js 文件  -----   api_exm.js

import request from '@/utils/request'

export function userSearch(name) 
  return request(
    url: '/sys/user',
    method: 'get',
    params:  name 
  )

然后在具体的组件中进行调用即可

import  userSearch from '@/api/api_exm'     //现在文件中导入需要使用的 js 文件
export default 
  data() 
    return 
        name: '测试aaa'
    
  ,
  methods:
      getUserInfo ()     //在方法中直接调用封装好的 axios 拦截器
          userSearch(this.name).then(res => 
           do......
              //可对 res.data 进行操作、处理或者渲染
          )
      
  ,
  mounted() 
      this.getUserInfo ();
  

axios 的理解和使用 axios.create(对axios请求进行二次封装) 拦截器 取消请求(axios.CancelToken)

axios 的理解和使用 axios.create(对axios请求进行二次封装) 拦截器 取消请求(axios.CancelToken)

 

 

axios是什么

  1. 前端最流行的 ajax请求库
  2. react/vue官方推荐使用axios发ajax请求
  3. 文档 https://github.com/axios/axios

axios特点

  1. 基于promise的异步ajax请求库
  2. 浏览器端/node端都可以使用
  3. 支持请求/响应拦截器
  4. 支持请求取消
  5. 请求/响应数据转换
  6. 批量发送多个请求

axios常用语法

namvalue
axios(config) 通用/最本质的发任意类型请求的方式
axios(url[,config]) 可以只指定url发get请求
axios.request(config) 等同于axios(config)
axios.get(url[,config]) 发get请求
axios.delete(url[,config]) 发delete请求
axios.post(url[,data,config]) 发post请求
axios.put(url[,data,config]) 发put请求
   
   
axios.defaults.xxx 请求非默认全局配置
axios.interceptors.request.use() 添加请求拦截器
axios.interceptors.response.use() 添加响应拦截器
   
   
axios.create([config]) 创建一个新的axios(他没有下面的功能)
   
   
axios.Cancel() 用于创建取消请求的错误对象
axios.CancelToken() 用于创建取消请求的token对象
axios.isCancel() 是否是一个取消请求的错误
axios.all(promise) 用于批量执行多个异步请求

axios安装

npm install axios
  • 1

vue项目使用
在main.js

import axios from ‘axios‘
Vue.prototype.$ajax = axios
  • 1
  • 2

html 直接导入就行了

<script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script>
  • 1

axios简单使用

默认get请求

// 配置默认基本路径
axios.defaults.baseURL = ‘http://localhost:3000‘

// 默认get请求
axios({
	url:"/posts",
	params:{
		id:1
	}
}).then(res=>{
	console.log(res)
},err=>{
    console.log(err)
})

 

 

post

// post请求
axios.post("/posts",{id:1}).then(res=>{
	console.log(res)
},err=>{
    console.log(err)
})

// 或

axios({
	url:"/posts",
	method:‘post‘
	data:{
		id:1
	}
}).then(res=>{
	console.log(res)
},err=>{
    console.log(err)
})

 

put

axios.put("/posts/4",{
      "title": "json-server---1",
      "author": "typicode",
    }).then(res=>{
	console.log(res)
},err=>{
    console.log(err)
})

// 或
axios({
	url:"/posts",
	method:‘put ‘
	data:{
      "title": "json-server---1",
      "author": "typicode",
    }
}).then(res=>{
	console.log(res)
},err=>{
    console.log(err)
})

 

 

delete

axios.delete("/posts/4",{
      "title": "json-server---1",
      "author": "typicode",
    }).then(res=>{
	console.log(res)
},err=>{
    console.log(err)
})

// 或
axios({
	url:"/posts",
	method:‘delete‘
	data:{
		id:1
	}
}).then(res=>{
	console.log(res)
},err=>{
    console.log(err)
})

 

 

axios难点语法

axios.create(config) 对axios请求进行二次封装

  1. 根据指定配置创建一个新的 axios ,也就是每个axios 都有自己的配置
  2. 新的 axios 只是没有 取消请求批量请求 的方法,其它所有语法都是一致的
  3. 为什么要这种语法?
    1. 需求,项目中有部分接口需要的配置与另一部分接口的配置不太一样
    2. 解决:创建2个新的 axios ,每个都有自己的配置,分别对应不同要求的接口请求中

简单使用

const instance = axios.create({
   baseURL:"http://localhost:3000"
})

// 使用instance发请求
instance({
    url:"/posts"
})

// 或
instance.get("/posts")

 

技术图片
同时请求 多个端口号

const instance = axios.create({
    baseURL:"http://localhost:3000"
})

const instance2 = axios.create({
    baseURL:"http://localhost:4000"
})

// 同时请求 端口号 3000 4000

// 使用instance发请求
instance({
    url:"/posts"
})

// 使用instance2发请求
instance2({
    url:"/posts"
})

 

 

axios的处理链流程 拦截器

拦截器简单使用
// 添加请求拦截器
axios.interceptors.request.use(config=>{
	// config 请求配置
    console.log("请求拦截器")
    return config
},err=>{
    return Promise.reject(err)
})  

// 添加响应拦截器
axios.interceptors.response.use(res=>{
	// res 响应结果
    console.log("响应拦截器")
    return res
},err=>{
    return Promise.reject(err)
})  

console.log("开始请求")
axios.get("http://localhost:3000/posts")
.then(res=>{
    console.log("res:",res)
    console.log("请求结束")
})

技术图片

多个拦截器

请求拦截器后添加先执行

// 添加请求拦截器
axios.interceptors.request.use(config=>{
    console.log("请求拦截器")
    return config
},err=>{
    return Promise.reject(err)
})  

axios.interceptors.request.use(config=>{
    console.log("请求拦截器--------2")
    return config
},err=>{
    return Promise.reject(err)
})  

axios.interceptors.request.use(config=>{
    console.log("请求拦截器--------3")
    return config
},err=>{
    return Promise.reject(err)
})  


// 添加响应拦截器
axios.interceptors.response.use(res=>{
    console.log("响应拦截器")
    return res
},err=>{
    return Promise.reject(err)
})  

axios.interceptors.response.use(res=>{
    console.log("响应拦截器---------2")
    return res
},err=>{
    return Promise.reject(err)
}) 

axios.interceptors.response.use(res=>{
    console.log("响应拦截器----------3")
    return res
},err=>{
    return Promise.reject(err)
})

console.log("开始请求")
axios.get("http://localhost:3000/posts")
.then(res=>{
    console.log("res:",res)
    console.log("请求结束")
})

 

 

技术图片

取消请求

1. 基本流程
配置 cancelToken 对象
缓存用于取消请求的 cancel 函数
在后面特定时机调用 cancel 函数取消请求
在错误回调中判断如果 error 是cancel ,做相应处理
  • 1
  • 2
  • 3
  • 4
2. 实现功能

node运行server.js
安装node和express (npm install express)

var http = require("http");

var express = require("express")
// var server = http.createServer();
var app = express()

// node跨域设置
app.all("*",function(req,res,next){
    //设置允许跨域的域名,*代表允许任意域名跨域
    res.header("Access-Control-Allow-Origin","*");
    //允许的header类型
    res.header("Access-Control-Allow-Headers","content-type");
    //跨域允许的请求方式 
    res.header("Access-Control-Allow-Methods","DELETE,PUT,POST,GET,OPTIONS");
    if (req.method.toLowerCase() == ‘options‘)
        res.send(200);  //让options尝试请求快速结束
    else
        next();
})


app.get(‘/‘,function(res,req){
    console.log("获取客户端请求",res);
    // 延迟响应 方便测试取消接口
    setTimeout(function(){
        req.end("延迟响应 方便测试取消接口"); //响应客户数据
    },5000)
    
})

app.listen(4000,function(){
    console.log("服务器启动成功,可以通过 http://127.0.0.1:4000 进行访问")
})

 

 

在cmd窗口

node server.js
  • 1

调用接口测试
axios.isCancel(err) //判断错误是否 是取消请求导致的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script>
</head>
<body>
    <script>
        let cancel;

        // axios({
        //     url:"http://localhost:4000",
        //     cancelToken:new axios.CancelToken(function(c){
        //         cancel = c
        //     })
        // })
        // 或

        axios.get("http://localhost:4000",{
            cancelToken:new axios.CancelToken(function(c){
                // c 用于取消当前请求的函数
                cancel = c
            })
        })
        .then(res=>{
            console.log("res:",res)
            cancel = null //请求完成,清空cancel
        },err=>{
            cancel = null 
            if(err.constructor.name === ‘Cancel‘){ //是取消请求导致的errer
                console.log("取消请求导致error:",err)
            }else{
                console.log("err:",err)
            }
			// 或
            // axios.isCancel(err) //判断错误是否 是取消请求导致的
        });

        setTimeout(function(){
            if(typeof(cancel) === ‘function‘){
                cancel(‘强制取消了请求‘)
            }else{
                console.log("没有可取消的请求")
            }
        },2000)
    </script>
</body>
</html>

 

 

正常请求
技术图片
取消接口

技术图片

在 请求拦截器里面统一添加取消请求
axios.interceptors.request.use(res=>{
  	res[‘cancelToken‘] = new axios.CancelToken(function(c){
        cancel = c
    })
    return res
},err=>{
    return Promise.reject(err)
})

 

 

在 响应拦截器里面统一添加 处理取消请求
axios.interceptors.response.use(res=>{
  
    return res
},err=>{
	if(axios.isCancel(err)){
		// 中断promise链接
		return new Promise(()=>{})
	}else{
		// 把错误继续向下传递
    	return Promise.reject(err)
	}
})

 

 

代码简化 实现上一个接口还未响应 下一个接口开始请求,把上一个接口取消
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script>
</head>
<body>
    <script>
        let cancel;

        axios.interceptors.request.use(config=>{
            // 实现上一个接口还未响应  下一个接口开始请求,把上一个接口取消
            if(typeof(cancel) === ‘function‘){
                cancel(‘强制取消了请求‘)
            }
            config[‘cancelToken‘] = new axios.CancelToken(function(c){
                cancel = c
            })
            return config
        },err=>{
            return Promise.reject(err)
        }) 

        axios.interceptors.response.use(res=>{
            cancel = null 
            return res
        },err=>{
            cancel = null 
            if(axios.isCancel(err)){
                console.log("取消上一个请求")
                // 中断promise链接
                return new Promise(()=>{})
            }else{
                // 把错误继续向下传递
                return Promise.reject(err)
            }
        })  
        function request(){
            axios.get("http://localhost:4000")
            .then(res=>{
                console.log("res:",res)
            },err=>{
                console.log("err:",err)
            });
        }
        
        request()
        request()
    </script>
</body>
</html>

 

 

技术图片

 

以上是关于axios 拦截器的主要内容,如果未能解决你的问题,请参考以下文章

请问,java高手,spring mvc拦截器如何拦截所有的请求啊,包括html和jsp页面?

没有 XML 的 Java Spring 拦截器

java filter 拦截器 怎么设置为在Spring框架的DispatcherServlet之前执行?

Spring拦截器获取request请求体中的json数据,并转换成Java对象的解决办法

Spring拦截器获取request请求体中的json数据,并转换成Java对象的解决办法

JAVA框架--hibernatestruts2spring