axios入门

375 阅读3分钟

1. JSON Server

支持跨域

1. 安装 JSON 服务器

npm install -g json-server

2. 创建db.json文件,复制下面内容

{
  "posts": [
    { "id": 1, "title": "json-server", "author": "typicode" }
  ],
  "comments": [
    { "id": 1, "body": "some comment", "postId": 1 }
  ],
  "profile": { "name": "typicode" }
}

3. 启动 JSON 服务器,注意要在db.json文件所在的文件夹下启动终端

json-server --watch db.json

image.png

2. axios

2.1. axios 是什么?

  1. 前端最流行的 ajax 请求库
  2. react/vue 官方都推荐使用 axios 发 ajax 请求
  3. axios速查表

2.2. axios 特点

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

2.3 直接使用axios发起请求

axios的基本使用

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>axios基本使用</title>
    <link crossorigin="anonymous" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css"
        rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>
<body>
    <div class="container">
        <h2 class="page-header">基本使用</h2>
        <button class="btn btn-primary"> 发送GET请求 </button>
        <button class="btn btn-warning"> 发送POST请求 </button>
        <button class="btn btn-success"> 发送 PUT 请求 </button>
        <button class="btn btn-danger"> 发送 DELETE 请求 </button>
    </div>
    <script>
        //获取按钮
        const btns = document.querySelectorAll('button');

        //第一个
        btns[0].onclick = function () {
            //发送 AJAX 请求
            axios({
                //请求类型
                method: 'GET',
                //URL
                  // url: 'http://localhost:3000/posts?id=2',
                url: 'http://localhost:3000/posts/2',
                //得到一个db.json中id=2的对象
            }).then(response => {
                console.log(response);
            });
        }

        //添加一篇新的文章
        btns[1].onclick = function () {
            //发送 AJAX 请求
            axios({
                //请求类型
                method: 'POST',
                //URL
                url: 'http://localhost:3000/posts',
                //设置请求体
                data: {
                //将data中的数据发送到对应的服务器
                    title: "今天天气不错, 还挺风和日丽的",
                    author: "张三"
                }
            }).then(response => {
                console.log(response);
            });
        }

        //更新数据
        btns[2].onclick = function () {
            //发送 AJAX 请求
            axios({
                //请求类型
                method: 'PUT',
                //URL
                url: 'http://localhost:3000/posts/3',
                //设置请求体
                data: {
                //将data中的数据更新到对应的服务器的相应路径
                    title: "今天天气不错, 还挺风和日丽的",
                    author: "李四"
                }
            }).then(response => {
                console.log(response);
            });
        }

        //删除数据
        btns[3].onclick = function () {
            //发送 AJAX 请求
            axios({
                //请求类型
                method: 'delete',
                //URL
                url: 'http://localhost:3000/posts/3',
                //删除对应路径中的数据
            }).then(response => {
                console.log(response);
            });
        }

    </script>
</body>
</html>

db.json虚拟哦服务器

{
  "posts": [
    {
      "id": 1,
      "title": "json-server",
      "author": "typicode"
    },
    {
      "id": 2,
      "title": "尚硅谷大厂学院上线啦",
      "author": "小编"
    }
  ],
  "comments": [
    {
      "id": 1,
      "body": "some comment",
      "postId": 1
    },
    {
      "body": "喜大普奔",
      "postId": 2,
      "id": 2
    }
  ],
  "profile": {
    "name": "typicode"
  }
}

2.4 axios 常用语法

  • 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(promises): 用于批量执行多个异步请求

  • axios.spread(): 用来指定接收所有成功数据的回调函数的方法

image.png

axios路径

    /**下方路径都是相等的
         * axios({
         *      url: '/post',
         *      //  /post?a=100&b=200
         *      //  /post/a/100/b/200
         *      //  /post/a.100/b.200
         *      params: {
         *          a:100,
         *          b:200
         *      }
         * })
         */

2.5 axios语法发起请求

<!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>
</head>
<body>
    <div>
        <button onclick="testGet()">GET请求</button>
        <button onclick="testPost()">POST请求</button>
        <button onclick="testPut()">PUT请求</button>
        <button onclick="testDelete()">DELETE请求</button>
    </div>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.js"></script>
    <script>
        function testGet() {
            axios.get('http://localhost:3000/posts') // 返回一个数组,数组里有两个对象
                // axios.get('http://localhost:3000/posts/1') // 返回一个对象
                // axios.get('http://localhost:3000/posts?id=1') // 返回一个数组,数组里有一个对象
                .then(response => {
                    console.log('/posts get', response.data)
                })
        }

        function testPost() { // 添加数据
            axios.post('http://localhost:3000/posts',
                {
                    "title": "json-server3", "author": "typicode"
                })
                .then(response => {
                    console.log('/posts put', response.data)
                })
        }

        function testPut() { // 更新数据
            axios.put('http://localhost:3000/posts/3',
                {
                    "title": "json-server_put", "author": "typicode"
                })
                .then(response => {
                    console.log('/posts post', response.data)
                })
        }

        function testDelete() { // 删除数据
            axios.delete('http://localhost:3000/posts/3')
                .then(response => {
                    console.log('/posts delete', response.data)
                })
        }
    </script>
</body>
</html>

2.6 axios全局(默认)配置

    <script>
        //获取按钮
        const btns = document.querySelectorAll('button');
        //默认配置
        axios.defaults.method = 'GET';//设置默认的请求类型为 GET
        axios.defaults.baseURL = 'http://localhost:3000';//设置基础 URL
        axios.defaults.params = { id: 2 };//配置默认参数
        axios.defaults.timeout = 3000;//超时设置

        btns[0].onclick = function () {
            axios({
                url: '/posts'
            }).then(response => {
                console.log(response);
            })
        }

    </script>

3. 难点语法的理解和使用

3.1 axios.create(config)

  • 根据指定配置创建一个新的 axios, 也就是每个新 axios 都有自己的配置

  • 新 axios 只是没有取消请求和批量发请求的方法, 其它所有语法都是一致的

为什么要设计这个语法?

  • 需求: 项目中有部分接口需要的配置与另一部分接口需要的配置不太一样, 如何处理(比如有多个baseURL需要指定)
  • 解决: 创建2 个新axios, 每个都有自己特有的配置, 分别应用到不同要求的接口请求中
const instance = axios.create({ // instance是函数类型
	baseURL: 'http://localhost:3000'
})
// 使用instance发Ajax请求
instance({
	url: '/posts'
})
instance.get('/posts')

创建实例

    <script>
        //创建实例对象  /getJoke
        const duanzi = axios.create({
            baseURL: 'https://api.apiopen.top',
            timeout: 2000
        });

        const another = axios.create({
            baseURL: 'https://b.com',
            timeout: 2000
        });
        //这里  duanzi 与 axios 对象的功能几近是一样的
        // duanzi({
        //     url: '/getJoke',
        // }).then(response => {
        //     console.log(response);
        // });

        duanzi.get('/getJoke').then(response => {
            console.log(response.data)
        })
    </script>

3.2 拦截器函数/ajax 请求/请求的回调函数的调用顺序

  • 说明: 调用axios()并不是立即发送ajax 请求, 而是需要经历一个较长的流程
  • 流程: 请求拦截器2 => 请求拦截器1 => 发ajax 请求 => 响应拦截器1 => 响应拦截器2 => 请求的回调
  • 注意: 此流程是通过 promise 串连起来的, 请求拦截器传递的是config, 响应拦截器传递的是response
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>拦截器</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>

<body>
    <script>
        // Promise
        // 设置请求拦截器  config 配置对象
        axios.interceptors.request.use(function (config) {
            console.log('请求拦截器 成功 - 1号');
            //修改 config 中的参数
            config.params = { a: 100 };
            // throw '失败'
            return config;
        }, function (error) {
            console.log('请求拦截器 失败 - 1号');
            return Promise.reject(error);
        });

        axios.interceptors.request.use(function (config) {
            console.log('请求拦截器 成功 - 2号');
            //修改 config 中的参数
            config.timeout = 2000;
            return config;
        }, function (error) {
            console.log('请求拦截器 失败 - 2号');
            return Promise.reject(error);
        });

        // 设置响应拦截器
        axios.interceptors.response.use(function (response) {
            console.log('响应拦截器 成功 1号');
            // 查看响应状态信息
            console.log(response);
            return response;
        }, function (error) {
            console.log('响应拦截器 失败 1号')
            return Promise.reject(error);
        });

        axios.interceptors.response.use(function (response) {
            console.log('响应拦截器 成功 2号')
            // 可以对响应结果做一些处理
            console.log(response.data);
            return response;
        }, function (error) {
            console.log('响应拦截器 失败 2号')
            return Promise.reject(error);
        });

        //发送请求
        axios({
            method: 'GET',
            url: 'http://localhost:3000/posts'
        }).then(response => {
            console.log('自定义回调处理成功的结果');
            // console.log(response);
        });
    </script>
</body>

</html>

image.png

3.3 取消请求

1. 基本流程

  1. 配置 cancelToken 对象
  2. 缓存用于取消请求的 cancel 函数
  3. 在后面特定时机调用 cancel 函数取消请求
  4. 在错误回调中判断如果 error 是 cancel, 做相应处理
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>取消请求</title>
    <link crossorigin='anonymous' href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>
<body>
    <div class="container">
        <h2 class="page-header">axios取消请求</h2>
        <button class="btn btn-primary"> 发送请求 </button>
        <button class="btn btn-warning" > 取消请求 </button>
    </div>
    <script>
        //获取按钮
        const btns = document.querySelectorAll('button');
        //2.声明全局变量
        let cancel = null;
        //发送请求
        btns[0].onclick = function(){
            //检测上一次的请求是否已经完成
            if(cancel !== null){
                //取消上一次的请求
                cancel();
            }
            axios({
                method: 'GET',
                url: 'http://localhost:3000/posts',
                //1. 添加配置对象的属性
                cancelToken: new axios.CancelToken(function(c){
                    //3. 将 c 的值赋值给 cancel
                    cancel = c;
                })
            }).then(response => {
                console.log(response);
                //将 cancel 的值初始化
                cancel = null;
            })
        }
        //绑定第二个事件取消请求
        btns[1].onclick = function(){
            cancel();
        }
    </script>   
</body>
</html>