axios

  2022年10月11日,在《AXAJ与JavaScript中的异步编程元素》文章中我总结了对于前端开发者中需要了解和掌握的8种异步编程元素,其中XMLHTTPRequest很关键,它是原生JavaScript提供的用于发送 HTTP 请求的对象,用于在前端与服务器进行数据交互。

  XMLHTTPRequest提供了基本的网络请求功能,但使用起来相对繁琐,需要编写大量的代码来处理不同阶段的请求、响应和错误,即使这些对这些处理做了很好的封装也一样。

  曾经很流行的JQuery中的AXAJ就是对XMLHTTPRequest进行了很好的封装,让开发者能够很方便灵活地使用。

  随着JQuery逐渐淡出,axios在很多前端框架中占据了主流(比如vue+elementUI框架),它也是对XMLHttpRequest(在Node.js 环境中封装的是http模块)进行了很好的封装,提供了一个更为优雅和强大的接口来发送 HTTP 请求。axios基于Promise,允许开发人员以链式调用的方式处理 HTTP 响应的成功和失败情况,从而简化了异步代码的书写和流程控制。

**  一、axios的常用方法**

  1. 发送 GET 请求:axios.get(url, config)。

  2. 发送 POST 请求:axios.post(url, data\[, config])。

  3. 发送 PUT 请求:axios.put(url, data\[, config])。

  4. 发送 DELETE 请求:axios.delete(url, config)。

  5. 发送 HEAD 请求:axios.head(url, config)。

  6. 发送 OPTIONS 请求:axios.options(url, config)。

  7. 发送 PATCH 请求:axios.patch(url, data\[, config])。

  axios 提供的各种方法分别对应HTTP规范中定义的不同请求方法,它们各自有不同的用途,通常与 RESTful API 设计标准保持一致,也是为了让axios操作更加语义化。

  对应的后端操作(NodeJS):

复制代码
constexpress=require('express');
constmyapp=express();

myapp.get('/api',(req,res)=>{
	//处理get请求
});

myapp.post('/api',(req,res)=>{
	//处理post请求
});

myapp.put('/api',(req,res)=>{
	//处理put请求
});

myapp.delete('/api',(req,res)=>{
	//处理delete请求
});

myapp.patch('/api',(req,res)=>{
	//处理patch请求
});

myapp.head('/api',(req,res)=>{
	//处理head请求
});

myapp.options('/api',(req,res)=>{
	//处理OPTIONS请求
});

  在平常的开发中,我们经常使用的是get和post方法,通常是在这两个操作中完成对数据的增、删、改、查。

**  二、axios的编码范式**

  axios是一个基于Promise的HTTP客户端,在JavaScript代码中使用axios库时,有几种常见的编码范式。

  以axios的get方法为例,下面是常见的用法。

  ⑴基本使用

复制代码
        axios.get('http://127.0.0.1:1234/user')
            .then(function (res) {
                console.log(res);
            })
            .catch(function (err) {
                console.error(err);
        });

        axios({
            url:'http://127.0.0.1:1234/user',
            method:'get'
        }).then(function (res) {
                console.log(res);
            })
            .catch(function (err) {
                console.error(err);
        });

  ⑵带有参数

复制代码
        axios.get('http://127.0.0.1:1234/user', {
            params: {
            ID: 2
            }
        })
        .then(function (res) {
            console.log(res);
        })
        .catch(function (err) {
            console.error(err);
        });

        axios({
            url:'http://127.0.0.1:1234/user', 
            method:'get',
            params: { ID: 2 }
        })
        .then(function (res) {
            console.log(res);
        })
        .catch(function (err) {
            console.error(err);
        });

  ⑶通过async/await使用

复制代码
        async function getUserInfo() {
            try {
                const res = await axios.get('http://127.0.0.1:1234/user?ID=2');
                console.log(res);
            } catch (err) {
                console.error(err);
            }
        }

        getUserInfo();

  ⑷创建axios实例

复制代码
        const myAxios = axios.create({
            baseURL: 'http://127.0.0.1:1234',
            timeout: 2000,
        });

        myAxios.get('/user?ID=2')
            .then(function (res) {
                console.log(res);
        }).catch(function (err) {
            console.error(err);
        });        

**  三、axios的链式编程**

  很多前端开发者喜欢链式编程写法。

  链式编程中如果任何一个请求发生错误,最后的catch方法都将捕获并统一处理错误,这是方便的地方,但是过多的链式编程给调试带来不必要的麻烦。

复制代码
        Mock.mock('http://127.0.0.1:1234/user?name=vue',{
            'user':{'Id':1 }
        })

        Mock.mock('http://127.0.0.1:1234/user?userId=1',{
            'info':{'title':'vue + elementUI + Admin' }
        })        

        axios.get('http://127.0.0.1:1234/user?name=vue')
        .then(function (res) {
            return res.data.user.Id;
        })
        .then(function (userId) {
            return axios.get('http://127.0.0.1:1234/user?userId='+userId);
        })
        .then(function (res) {
            console.log(res.data.info.title);
        })
        .catch(function (err) {
            console.err(err);
        });

  程序最后输出:vue + elementUI + Admin。

**  四、axios处理并发请求**

复制代码
        Mock.mock('http://127.0.0.1:1234/getUserName',{            
                        'name':'vue'             
        })

        Mock.mock('http://127.0.0.1:1234/getUserInfo',{
                        'Framework':'vue + elementUI + Admin' 
        })

        function getUserName() {
            return axios.get('http://127.0.0.1:1234/getUserName');
        }

        function getUserInfo() {
            return axios.get('http://127.0.0.1:1234/getUserInfo');
        }

        Promise.all([getUserName(), getUserInfo()])
        .then(function (res) {
            const arr1 = res[0];
            const arr2 = res[1];
            // 处理结果
            console.log(arr1.data.name);
            console.log(arr2.data.Framework);
        });

        axios.all([getUserName(), getUserInfo()])
        .then(function (res) {
            const arr1 = res[0];
            const arr2 = res[1];
            // 处理结果
            console.log(arr1.data.name);
            console.log(arr2.data.Framework);
        });

  如果不使用axios.all()或者Promise.all()来执行,让两个axios单独执行,那么可能由于axios完成时间的不同,导致不同的axios获取结果存在先后顺序;但是放在axios.all()或者Promise.all()中来执行,那么就是等待这两个都完成再一起输出结果。

  现在流行的写法是使用箭头函数:

复制代码
        axios.all([getUserName(), getUserInfo()])
            .then(res=>{
                console.log(res);
                for(let i=0;i<res.length;i++){
                    console.log(res[i].data);
                }
        });        

  或者:

复制代码
        axios.all([getUserName(), getUserInfo()])
            .then(axios.spread(
                (res1,res2) => {
                console.log(res1.data.name);
                console.log(res2.data.Framework);
        }));    

**  五、创建axios实例**

  一般写法:

复制代码
        const myAxios=axios.create();

        myAxios.defaults.baseURL="http://127.0.0.1:1234";

        myAxios.request({
            method:'get',
            url:'/user',
            timeout: 2000,
            headers: {'X-Custom-Header': 'foobar'}            
        }).then(
            res=>{ console.log(res.data.name); }
        )

  或者:

复制代码
        const myAxios=axios.create({
            baseURL:"http://127.0.0.1:1234",
            timeout: 2000,
            headers: {'X-Custom-Header': 'foobar'}            
        });

        myAxios.request({
            method:'get',
            url:'/user',
        }).then(
            res=>{ console.log(res.data.name); }
        )

**  六、axios拦截器**
  拦截操作就是在axios进行操作之前进行一些系统需要统一处理的操作,比如可以验证用户、检查请求的合法性、检查数据的完整性等等。

复制代码
        Mock.mock('http://127.0.0.1:1234/user',{            
                        'name':'JavaScript'             
        })

        const myAxios=axios.create({
            baseURL:"http://127.0.0.1:1234",
            timeout: 2000,
            headers: {'X-Custom-Header': 'foobar'}            
        });

        myAxios.interceptors.request.use(
            request=>{
                console.log("检查请求...");
                return request
            }
        )

        myAxios.interceptors.response.use(
            response=>{
                console.log("检查返回数据...");
                return response
            }
        )

        myAxios.request({
            method:'get',
            url:'/user',
        }).then(
            res=>{ console.log(res.data.name); }
        )

  上面执行的结果显示如下:

复制代码
检查请求...
检查返回数据...
JavaScript
相关推荐
香芋芋圆2 小时前
AI 冲击内卷之下,普通前端如何破局?WebGIS—— 低门槛突围赛道
前端·javascript·人工智能·学习·职场发展
INS_KF2 小时前
【编程笔记】成员函数中两个 const 的区别(const Data &getData() const;)
前端·javascript·笔记
宿6743 小时前
vue3-async
前端·javascript·vue.js
excel4 小时前
Nuxt + Twin CSS 中宽度超过屏幕时底部出现空白的原因与解决方案
前端·javascript
一个游离的指针7 小时前
函数管道:消除深度嵌套调用
前端·javascript
柚yuzumi7 小时前
前端优化,从少触发一次开始:防抖与节流
前端·javascript
默_笙8 小时前
🚤 CSS 布局的"圈地运动":BFC 就是浏览器的独立领地
前端·javascript
用户938515635078 小时前
大模型记忆指南:从短时缓存到永久记忆,手把手带你吃透 LangChain Memory 管理
javascript·人工智能
xqchen8 小时前
Web Components 普及困境深度解析:技术标准与工程实践的落差
javascript
爱丶不疚8 小时前
写给前端工程师的现代 Python 工程化最佳实践:从 pnpm 到 uv,从 CommonJS 到 src-layout
javascript·python·typescript