前端开发日记 # axios

144 阅读4分钟

简介

是一个基于Promise的网络请求库,可用于浏览器和Node

功能

  • 从浏览器中创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF

发送请求方式

1、利用axios构造函数进行发送请求

axios({
    url,
    method,
    data
})

2、利用axios函数对象的方法进行发送请求

axios.request(config)
axios.get(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.delete(url[, config])

3、利用axios创建对象进行发送请求

const http = axios.create(config)

注意:当接口服务并非来自单一的服务器接口时,使用此方式最适合

响应数据格式

使用axios发送请求后,将收到服务器响应数据,axios对响应数据进行一次转换,最终得到响应数据格式如下:

{
    config: {},        // axios配置对象,例如:请求头、url、请求方式、请求数据
    data: {},          // 响应体信息(响应数据)
    headers: {},       // 响应头信息
    request: {},       // 原生请求对象XHR
    status: 200,       // 状态码
    statusText: 'ok'   // 状态码描述
}

注意:服务器返回的数据就放在data属性里

请求配置对象介绍

axios发送请求时,可以传入一个config配置对象,需要看下有哪些配置项能配置

url

指定请求URL

method

指定请求方式,例如:'get'、'post'

baseURL

指定基础URL,例如:请求协议、域名、端口等

timeout

指定超时时间,超过时间还没收到响应,就会返回请求超时

headers

指定请求头信息,例如:Content-type、token

params

指定URL查询字符串,不止GET方式,其他方式也可以指定

data

指定请求体携带的数据,只适用于methodPOST、PUT、PATCH

默认配置

当每次请求时,发现很多配置值都是一模一样,这时编码冗余,需要使用默认配置进行优化,代码如下:

axios.defaults.baseURL = 'https://api.example.com:3000';
axios.defaults.method = 'get';
axios.defaults.timeout = 30000;

拦截器

请求拦截器

对请求参数和内容进行检查,通过就放行,不通过就终止请求

axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
}, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
});
1、回调函数中可以返回什么值
  • 成功回调函数(第一个传参)
1、正确返回配置对象 `return config` <br/>
2、如果检查配置有错,抛出错误 `throw "xxx出错了"` 或者 `return Promise.reject('xxx')`
  • 失败返回配置对象(第二个传参)
1、抛出错误 `throw "xxx出错了"` 或者 `return Promise.reject('xxx')`

注意:当有多个请求拦截器时,无论成功回调还是失败回调,最后执行的回调如果是抛出错误 throw "xxx出错了" 或者 return Promise.reject('xxx'),请求都不会发送,直接就会触发响应拦截器第二个回调函数

2、传参中的第二个回调函数什么时候触发运行?

一直很迷茫,在官方文档中,对这个回调函数注释到:对请求错误做些什么,但请求会有什么错误呢?莫非就是请求参数错误

这让我一度以为axios内置请求参数检查功能,但我发现哪怕请求参数有错,但还是执行第一个回调函数,而没有执行第二个回调函数,证明axios没有内置请求参数检查功能,无论怎样都不能触发执行第二个回调,最后去查看了源码,找到了答案

image.png

从上面来看,无论做什么,都只会执行第一个回调函数,而第二个函数只有在定义多个请求拦截器时,才有可能执行,所以如果只定义一个请求拦截器时,无须传第二个回调函数作为参数

const requester = axios.create({
    baseURL: 'http://localhost',
    timeout: 30000,
    method: 'get'
})

// 只定义一个请求拦截器的情况
requester.interceptors.request.use(
    function (config) {
        // 在发送请求之前做些什么
        if (config.timeout > 2000) {
            throw '请求出错啦啦啦'
        }else{
            return config
        }
    }
)

// 定义多个个请求拦截器的情况
requester.interceptors.request.use(
    function (config) {
        // 在发送请求之前做些什么
        if (config.timeout > 2000) {
            throw '请求出错啦啦啦'
        }else{
            return config
        }
    },
    function (error){
        // 对请求错误做些什么
        return Promise.reject(error)
    }
)

requester.interceptors.request.use(
    function (config) {
        // 在发送请求之前做些什么
        if (config.timeout > 2000) {
            throw '请求出错啦啦啦'
        }else{
            return config
        }
    }
)

响应拦截器

对响应结果进行检查或格式化,统一错误处理等

axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    return response;
}, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
});

请求拦截器执行顺序

先定义的后执行,后定义的先执行

响应拦截器执行顺序

先定义的先执行,后定义的后执行

取消请求

let cancel = null

axios({
    method: 'get',
    url: '/api/v1/admin/getList',
    cancelToken: new axios.CancelToken(function(c){
        cancel = c
    })
})

// 事件触发停止请求
$('#btn').on('click', function(e){
    cancel();
})