• 【前端之旅】Axios看这一篇就够了


    在这里插入图片描述

    一名软件工程专业学生的前端之旅,记录自己对三件套(HTML、CSS、JavaScript)、Jquery、Ajax、Node.js、Vue、Axios、小程序开发(Uniapp)以及各种UI组件库、前端框架的学习。

    【前端之旅】Web基础与开发工具
    【前端之旅】手把手教你安装VS Code并附上超实用插件指南
    【前端之旅】HTML大总结
    【前端之旅】CSS三万字总结
    【前端之旅】JavaScript学习笔记
    【前端之旅】Web前端发展简史
    【前端之旅】JavaScript进阶笔记
    【前端之旅】快速上手JSON
    【前端之旅】一文掌握AJAX技术
    【前端之旅】Axios看这一篇就够了
    【前端之旅】响应式布局及Bootstrap框架
    【前端之旅】Node.js安装教程(图文版)
    【前端之旅】Webpack模块打包工具
    【前端之旅】uni-app学习笔记
    【前端之旅】手把手教你将uView UI配置到uniapp项目中
    【前端之旅】Nginx快速入门


    image-20220831005532065

    官网:https://www.axios-http.cn

    Axios 是一个基于 Promise 的 HTTP 客户端,同时支持浏览器和 Node.js 环境,它是一个优秀的 HTTP 客户端,被广泛地应用在大量的 Web 项目中,拥有以下特性:

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

    一、快速入门

    1、引入axios的jsCDN文件

    // 使用 jsDelivr CDN:
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    
    • 1
    • 2

    2、使用axios发送请求,并获取响应结果

    // get方式
    axios({
        method:"get",
        url:"http://localhost:8080/ajax-demo/axiosServlet?username=sunbujian"
    }).then(function (resp){
        alert(resp.data)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    // post方式
    axios({
        method:"post",
        url:"http://localhost:8080/ajax-demo/axiosServlet",
        data:"username=sunbujian"
    }).then(function (resp){
        alert(resp.data)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    二、Axios介绍

    axios是基于Promise的,因此可以使用Promise API。

    1.axios可以请求的方法:

    1. get:获取数据,请求指定的信息,返回实体对象
    2. post:向指定资源提交数据(例如表单提交或文件上传)
    3. put:更新数据,从客户端向服务器传送的数据取代指定的文档的内容
    4. patch:更新数据,是对put方法的补充,用来对已知资源进行局部更新
    5. delete:请求服务器删除指定的数据
    6. head:获取报文首部

    2.请求方法别名

    为了方便起见,axios为所有支持的请求方法提供了别名:

    1. axios(config)
    2. axios.request(config)
    3. axios.get(url [,config])
    4. axios.post(url [,data [,config]])
    5. axios.put(url [,data [,config]])
    6. axios.delete(url [,config])
    7. axios.patch(url [,data [,config]])
    8. axios.head(url [,config])

    get、post请求代码示例:

    //执行GET请求
    import axios from 'axios'
    axios.default.baseURL = 'http://localhost:8080/ajax-demo/axiosServlet'
    axios.get('/user?ID=12345')  //返回的是一个Promise
        .then(res=>console.log(res))
        .catch(err=>console.log(err));
    //可配置参数的方式
    axios.get('/user',{
        params:{
            ID:12345
        }
    }).then(res=>console.log(res))
      .catch(err=>console.log(err));
    
    //发送post请求
    axios.post('/user',{
        firstName: 'bujian',
        lastName:'sun'
    }).then(res=>console.log(res))
      .catch(err=>console.log(err));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3.并发请求

    通过axios.all(iterable)可实现发送多个请求,参数不一定是数组,只要有iterable接口就行,函数返回的是一个数组

    axios.spread(callback)可用于将结果数组展开

    axios.all([
    	axios.get('/goods.json'),
    	axios.get('/class.json')
    ]).then(axios.spread((goodsRes,classRes)=>{
    	console.log(goodsRes.data);
    	console.log(classRes.data);
    }))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    三、Axios API

    1.向 axios 传递相关配置来创建请求

    代码示例:

    1.axios(config)
    // 发送 POST 请求
    axios({
      method: 'post',
      url: '/user/1208',
      data: {
        firstName: 'bujian',
        lastName: 'sun'
      }
    });
     
    2.axios(url[config])
    // 默认发送 GET 请求
    axios('/user/1208');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.用axios提供的请求方法发送请求

    代码示例:

    1.axios.get(url[config])  执行 GET 请求
    // 向具有指定ID的用户发出请求
    axios.get('/user?ID=1208').then(function (res) {
        console.log(res);
    }).catch(function (err) {
        console.log(err);
    });
    
    // 也可以通过 params 对象传递参数
    axios.get('/user', {
        params: {
            ID: 1208
        }
    }).then(function (res) {
        console.log(res);
    }).catch(function (err) {
        console.log(err);
    });
     
    2.axios.post(url[, data[, config]]) 
    // 执行 POST 请求
    axios.post('/user', {
        firstName: 'bujian',
        lastName: 'sun'
    }).then(function (res) {
        console.log(res);
    }).catch(function (err) {
        console.log(err);
    });
    
    3.axios.request(config)//用法同上
    4.axios.head(url[, config])//用法同上
    5.axios.delete(url[, config])//用法同上
    6.axios.put(url[, data[, config]])//用法同上
    7.axios.patch(url[, data[, config]])//用法同上
    
    8.axios.all(iterable)执行多个并发请求
    9.axios.spread(callback)展开
    
    function getUserAccount() {
        return axios.get('/user/12345');
    }
    
    function getUserPermissions() {
        return axios.get('/user/12345/permissions');
    }
    
    axios.all([getUserAccount(), getUserPermissions()])
        .then(axios.spread(function (acct, perms) {
        // 两个请求现在都执行完成
    }));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    四、Axios实例及配置方法

    1.创建axios实例

    axios.create([config])

    可以同时创建多个axios实例。

    代码示例:

    const instance = axios.create({
      baseURL: 'http://localhost:8080/ajax-demo/axiosServlet',
      timeout: 1000,
      headers: {'X-Custom-Header': 'foobar'}
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5

    实例方法

    以下是可用的实例方法。指定的配置将与实例的配置合并。

    • axios#request(config)
    • axios#get(url[, config])
    • axios#delete(url[, config])
    • axios#head(url[, config])
    • axios#options(url[, config])
    • axios#post(url[, data[, config]])
    • axios#put(url[, data[, config]])
    • axios#patch(url[, data[, config]])
    • axios#getUri([config])

    2.配置方法

    2.1 配置对象常用的配置项

    这些是创建请求时可以用的配置选项。只有 url 是必需的。如果没有指定 method,请求将默认使用 GET 方法。更多配置项请查看官方文档,戳我传送

    {
      // 路径url
      url: '/user',
    
      // 请求方法,默认get
      method: 'get', 
        
      //基础url,最终请求的url是 baseURL+url拼接,所以再全局设置默认,可以使得发送请求时的url变得简洁
      baseURL: 'https://localhost:8080/api/',
    
      //设置请求头
      headers: {'X-Requested-With': 'XMLHttpRequest'},
    
      //设置请求url的query参数,可以使得url简洁。
      //比如url是https://localhost:8080/api/user  然后params如下设置,那么最终的url是:
      //https://localhost:8080/api/user?ID=12345&name=sunbujian
      params: {
        ID: 1208,
        name:"sunbujian"
      },
    
     //设置请求体
      data: {
        firstName: 'bujian'
      },
      
      //设置请求的另外一种格式,不过这个是直接设置字符串的
      data: 'Country=Brasil&City=Belo Horizonte',
    
     //请求超时,单位毫秒,默认0,不超时。
      timeout: 1000,
    
      //响应数据类型,默认json
      responseType: 'json', 
    
      //响应数据的编码规则,默认utf-8
      responseEncoding: 'utf8',
    
    	//响应体的最大长度 
      maxContentLength: 2000,
    
      // 请求体的最大长度
      maxBodyLength: 2000,
    
      //设置响应状态码为多少时是成功,调用resolve,否则调用reject失败
      //默认是大于等于200,小于300
      validateStatus: function (status) {
        return status >= 200 && status < 300; 
      },
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    2.2 默认配置

    可以设置全局默认配置,是为了避免多种重复配置在不同请求中重复,比如baseURL、timeout等,这里设置baseURL。

    2.3 全局 axios 默认值

    axios.defaults.baseURL = 'https://localhost:8080';
    axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
    axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
    
    • 1
    • 2
    • 3

    2.4 自定义实例默认值

    // 创建实例时配置默认值
    const instance = axios.create({
      baseURL: 'https://localhost:8080'
    });
    
    // 创建实例后修改默认值
    instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.5 配置的优先级

    配置将会按优先级进行合并。它的顺序是:在 lib/defaults.js 中找到的库默认值,然后是实例的 defaults 属性,最后是请求的 config 参数。后面的优先级要高于前面的

    五、拦截器

    在请求或响应被 then 或 catch 处理前拦截它们,自定义的axios实例也可添加拦截器,如:

    const instance = axios.create();
    instance.interceptors.request.use(function () {/*...*/});
    
    • 1
    • 2

    1.请求拦截器

    示例代码:

    // 添加请求拦截器
    axios.interceptors.request.use(function (config) {
        // 在发送请求之前做些什么
        return config;
      }, function (error) {
        // 对请求错误做些什么
        return Promise.reject(error);
      });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2. 响应拦截器

    示例代码:

    // 添加响应拦截器
    axios.interceptors.response.use(function (response) {
        // 2xx 范围内的状态码都会触发该函数。
        // 对响应数据做点什么
        return response;
      }, function (error) {
        // 超出 2xx 范围的状态码都会触发该函数。
        // 对响应错误做点什么
        return Promise.reject(error);
      });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3. 取消拦截器

    示例代码:

    const myInterceptor = axios.interceptors.request.use(function () {/*...*/});
    axios.interceptors.request.eject(myInterceptor);
    
    • 1
    • 2

    六、Axios封装

    先设计我们想要这个通用请求能达到什么样的效果:

    • 优化配置,设置默认配置项(responseType、跨域携带cookie、token、超时设置)
    • 统一设置请求头
    • 根据环境设置 baseURL
    • 通过 Axios 方法直接发起请求
    • 添加请求拦截器
    • 添加响应拦截器
    • 导出 Promise 对象
    • 封装 Post 方法,精简 post 请求方式
    • 封装 Get 方法,精简 get 请求方式
    • 请求成功,配置业务状态码
    • 全局的loading配置

    我们需要根据不同的需求进行不同程度的封装,这里介绍一下封装方法,就不一一进行二次封装实现

    // src/api/axios.js
    import axios from "axios";
    import Qs from 'qs'
    import store from '@/store'
    import { getToken } from '@/utils/auth'
    
    export const Axios = (url,method='get',params={},headers={})=>{
        // 根据定义的环境状态,切换不同的 baseURL 开发环境使用代理, 生产环境可以直接使用域名全拼
        const BaseUrl = process.env.NODE_ENV==='development'? '' : process.env.BASEURL;
        let defaultHeaders = {
            'Content-Type': 'application/json;charset=UTF-8',
            // 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8', // 指定提交方式为表单提交 或上传
            // 'Content-Type' :'multipart/form-data;charset=UTF-8',
            'Accept': 'application/json', // 通过头指定,获取的数据类型是JSON
            // 'Access-Control-Allow-Origin': 'true',
            // 'Access-Control-Allow-Credentials': 'true',
        }
        if(headers){
            for (let i in headers) {
                defaultHeaders[i] = headers[i];
            }
        }
    //在响应拦截中,如果有需要还可以对状态码提示进行处理。现在项目一般后端都会给处理好,
    //这个根据自己的项目情况进行配置,这里只做部分常见的示例
        const showResState = (state) => {
            let message = ''
            switch (state) {
                case 400:
                    message = '请求错误(400)'
                    break
                case 401:
                    message = '未授权,请重新登录(401)'
                    break
                case 403:
                    message = '拒绝访问(403)'
                    break
                case 404:
                    message = '请求出错(404)'
                    break
                case 500:
                    message = '服务器错误(500)'
                    break
                case 501:
                    message = '服务未实现(501)'
                    break
                case 502:
                    message = '网络错误(502)'
                    break
                case 503:
                    message = '服务不可用(503)'
                    break
                default:
                    message = `连接出错(${state})!`
            }
            return `${message},请检查网络或联系网站管理员!`
        }
    
        // 添加请求拦截器
        axios.interceptors.request.use( config =>  {
        // 在发送请求之前做些什么
    
       // header 配置 Token 判断Token是否过期 没过期则正常处理 过期则发起刷新Token的请求拿到新的Token保存
            config.headers.Authorization = null;
            // if (store.getters.token) {
         // config.headers['token'] = getToken()
        //}
           //else{
           // alert("Token已失效")
         // }
            return config;
        }, function (error) {
            // 对请求错误做些什么
            return Promise.reject(error);
        });
    
        // 添加响应拦截器
        axios.interceptors.response.use((res) => {
            // 对响应数据做点什么
            const status = res.status;
            let msg = ''
            if (status < 200 || status >= 300) {
                // 处理http错误,抛到业务代码
                msg = showResState(status)
                
                if (typeof res.data === 'string') {
                   res.data = { msg }
                } else {
                   res.data.msg = msg
                }
            }
            return res;
        }, function (error) {
            // 对响应错误做点什么
            return Promise.reject(error);
        });
    
        // 1. 执行异步ajax请求
        const instance = axios({
            // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
            // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
            baseURL: BaseUrl,
    
            // `url` 是用于请求的服务器
            url: url,
    
            // `method` 是创建请求时使用的方法
            method: method || 'get',
    
            // mode: 'cors',
            // cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
    
            // `headers` 是即将被发送的自定义请求头
            headers: {...defaultHeaders},
    
            // `transformRequest` 允许在向服务器发送前,修改请求数据
            // 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法
            // 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream
            transformRequest: [function (data, headers) {
                // 对 data 进行任意转换处理
                return data;
            }],
    
            // `transformResponse` 在传递给 then/catch 前,允许修改响应数据
            transformResponse: [function (data) {
                // 对 data 进行任意转换处理
                return data;
            }],
    
            // `params` 是即将与请求一起发送的 URL 参数
            // 必须是一个无格式对象(plain object)或 URLSearchParams 对象
            params: method === 'get' ? params || {} : {},
    
            // `paramsSerializer` 是一个负责 `params` 序列化的函数
            paramsSerializer: function(params) {
                return Qs.stringify(params, {arrayFormat: 'brackets'})
            },
    
            // `data` 是作为请求主体被发送的数据
            // 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH'
            // 在没有设置 `transformRequest` 时,必须是以下类型之一:
            // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
            // - 浏览器专属:FormData, File, Blob
            // - Node 专属: Stream
            data: method === 'post' ? params || {} : {},
    
            // `timeout` 指定请求超时的毫秒数(0 表示无超时时间)
            // 如果请求话费了超过 `timeout` 的时间,请求将被中断
            timeout: 0,
    
            // `withCredentials` 表示跨域请求时是否需要使用凭证
            withCredentials: false, // default 为true则产生跨域,跨域携带cookie
    
            // `responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
            responseType: 'json', // default
        });
    
        return new Promise((resolve, reject) => {
            instance.then(response => {
                // 2. 如果成功了, 调用resolve(value)
                resolve(response);
            })
                .catch(error => {
                    // 3. 如果失败了, 不调用reject(reason), 而是提示异常信息
                    reject(error)
                }).finally(() => {
            })
        });
    }
    
    // GET 请求 get 下 params 为查询参数
    export const Get = (url,params={},headers={}) => {
        return Axios(url,'get',params,headers)
    }
    
    // POST 请求 post 下 params 为body参数, 如果 post 下既需要传查询参数也需要传实体参数,则查询参数配置在 url 中
    export const Post = (url,params={},headers={}) => {
        return Axios(url,'post',params,headers)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
  • 相关阅读:
    关于cvxpy库使用过程中的一个warning
    Vue2升级到Vue3应该知道的事
    最大单词长度乘积(w位运算)
    vue中反向代理pathRewite的理解
    计算机毕业设计--基于SSM+Vue的物流管理系统的设计与实现
    Pom文件的依赖与starter启动器的作用
    使用 pnpm 管理全栈、多包 monorepo
    什么是Wi-Fi保护设置(WPS),以及如何使用它?这里有详细解释
    【LeetCode-中等题】347. 前 K 个高频元素
    基于Java SSM仓库管理系统
  • 原文地址:https://blog.csdn.net/qq_51808107/article/details/127456907