axios

一、使用json-serve搭建REST API

1.1 json-serve简介

json-serve可以快速搭建一个具有RESTful风格的后台服务器,为前端提供后台的接口和数据的调用。

json-serve官网:json-serve

1.2 json-serve的安装
  1. 下载json-serve包
npm install -g json-server
  1. 创建包含某些数据的文件db.json,用于存放前台要调用的数据
{
  "posts": [
    { "id": 1, "title": "json-server", "author": "typicode" }
  ],
  "comments": [
    { "id": 1, "body": "some comment", "postId": 1 }
  ],
  "profile": { "name": "typicode" }
}
  1. 启动 JSON 服务器
json-server --watch db.json

4.访问http://localhost:3000/posts/1,你会得到

{ "id": 1, "title": "json-server", "author": "typicode" }
  • 如果您发出 POST、PUT、PATCH 或删除请求,更改将自动安全地保存到db.json文件中
  • 您的请求正文 JSON 应是对象封闭,就像 GET 输出一样。(例如{"name": "Foobar"})
  • ID 值不可更改。PUT 或 PATCH 请求正文中的任何ID值都将被忽略。仅使用POST 请求中设置的值,且该值的键符合db.json文件中定义的键的值。

二、axios

2.1 axios简述

axios官网:axios

  1. 基于Promise的HTTP客户端,用于浏览器和node.js
  2. 前端最流行的 ajax 请求库
  3. react/vue 官方都推荐使用 axios 发 ajax 请求
2.2 axios特点
  1. 基本 promise 的异步 ajax 请求库
  2. 浏览器端、node 端都可以使用
  3. 支持请求响应拦截器
  4. 支持请求取消
  5. 请求、响应数据转换
  6. 批量发送多个请求
2.3 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():用来指定接收所有成功数据的回调函数的方法
2.4 axios的基本使用
  1. 启动json-serve后台接口服务器
  2. 下载并引入axios包和基本的样式文件

基本使用1:记得导入axios包

<!DOCTYPE html>
<html lang="en">
<head>
    <!-- 引入样式文件和axios包 -->
    <link href="https://cdn.bootcdn.net/ajax/libs/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>
    <title>Axios基本使用</title>
</head>
<body>
    <div class="container">
        <h2 class="page-header">Axios基本使用</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 btn = document.querySelectorAll('button');

        //发送ajax请求,类型为GET
        //从服务度获取指定id的json数据
        btn[0].onclick = function() {
            axios({
                method: 'get',
                url: 'http://localhost:3000/posts/3'
            }).then((result) => {
                console.log(result)
            });
        }
        //发送ajax请求,类型为POST
        //添加一条数据
        btn[1].onclick = function() {
            axios({
                method: 'post',
                url: 'http://localhost:3000/posts',
                data: {title: "朱阳策", author: "沈峤" }
            }).then((result) => {
                console.log(result)
            });
        }
         //发送ajax请求,类型为PUT
        //修改指定id的数据
         btn[2].onclick = function() {
            axios({
                method: 'put',
                url: 'http://localhost:3000/posts/2',
                data: {title: "朱阳策", author: "沈峤" }
            }).then((result) => {
                console.log(result)
            });
        }
         //发送ajax请求,类型为Delete
        //删除指定id的数据
         btn[3].onclick = function() {
            axios({
                method: 'delete',
                url: 'http://localhost:3000/posts/3',
            }).then((result) => {
                console.log(result)
            });
        }
    </script>
</body>
</html>

基本使用2

<!DOCTYPE html>
<html lang="en">
<head>
    <!-- 引入样式文件和axios包 -->
    <link href="https://cdn.bootcdn.net/ajax/libs/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>
    <title>Axios基本使用</title>
</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 btn = document.querySelectorAll('button');

        //发送ajax请求,类型为get
        //获取指定id的数据
        btn[0].onclick = function() {
            axios.request({
                method: 'get',
                url: 'http://localhost:3000/posts/3'
            }).then((result) => {
                console.log(result)
            });
        }
        
        //发送ajax请求,类型为POST
        //添加一条数据
        btn[1].onclick = function(){
            axios.post('http://localhost:3000/comments',
            {
                body: "上阳",
                postId: 1
            }).then((result) => {
                console.log(result)
            })
        }

         //发送ajax请求,类型为PUT
         //修改指定id的数据
         btn[2].onclick = function() {
             axios.put('http://localhost:3000/posts/2',
             {
                title: "天天", author: "沈峤"
             }).then((result) => {
                console.log(result)
            });
        }

         //发送ajax请求,类型为Delete
         //删除指定id的数据
         btn[3].onclick = function() {
             axios.delete('http://localhost:3000/posts/3').then((result) => {
                console.log(result)
            });
        }
    </script>
</body>
</html>
2.5 axios的默认配置
<!DOCTYPE html>
<html lang="en">
<head>
    <!-- 引入axios资源包文件 -->
    <link href="https://cdn.bootcdn.net/ajax/libs/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>
    <title>axios的默认配置</title>
</head>
<body>
    <div class="container">
        <h2 class="page-header">axios的默认配置</h2>
        <button class="btn btn-primary">发送GET请求</button>
    </div>

    <script>
        //获取按钮 
        const btn = document.querySelectorAll('button');
        //配置axios的默认配置,使用默认的配置可以减少url的地址,和一些重复的基础配置
        axios.defaults.baseURL = 'http://localhost:3000/'
        axios.defaults.method = 'get'
        axios.defaults.params = {id:1}
        axios.defaults.timout = 3000

        //发送ajax请求,类型为get
        btn[0].onclick = function() {
            axios.request({
                url: '/posts'
            }).then((result) => {
                console.log(result)
            });
        }
    </script>

</body>
</html>
2.6 创建axios对象
  1. 根据指定配置创建一个新的 axios, 也就就每个新 axios 都有自己的配置
  2. 新 axios 只是没有取消请求和批量发请求的方法, 其它所有语法都是一致的
  3. 为什么要设计这个语法?
    • 需求: 项目中有部分接口需要的配置与另一部分接口需要的配置不太一 样, 如何处理
    • 解决: 创建 2 个新 axios, 每个都有自己特有的配置, 分别应用到不同要 求的接口请求中
<!DOCTYPE html>
<html lang="en">
<head>
    <link href="https://cdn.bootcdn.net/ajax/libs/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>
    <title>创建Axios对象</title>
</head>
<body>
    <div class="container">
        <h2 class="page-header">创建Axios对象</h2>
        <button class="btn btn-primary">发送GET请求</button>
    </div>


    <script>
        //获取按钮 
        const btn = document.querySelectorAll('button');
        //创建axios对象,并配置基本的配置
        const instance = axios.create({
            baseURL: 'http://localhost:3000/',
            timeout: 2000
        });

        //发送ajax请求,类型为get
        btn[0].onclick = function() {
            //使用创建的对象来发送get请求
            instance.get('/posts').then(result => {
                console.log(result)
            })
        }

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

三、axios的拦截器

  1. 说明: 调用 axios()并不是立即发送 ajax 请求, 而是需要经历一个较长的流程
  2. 流程: 请求拦截器2 => 请求拦截器 1 => 发ajax请求 => 响应拦截器1 => 响 应拦截器 2 => 请求的回调
  3. 注意: 此流程是通过 promise 串连起来的, 请求拦截器传递的是 config, 响应 拦截器传递的是 response
<!DOCTYPE html>
<html lang="en">
<head>
    <!-- 导入axios包 -->
    <link href="https://cdn.bootcdn.net/ajax/libs/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>
    <title>axios拦截器</title>
</head>
<body>
    <div class="container">
        <h2 class="page-header">axios拦截器</h2>
        <button class="btn btn-primary">发送GET请求</button>
    </div>

    <script>
        // 添加一个请求拦截器,config为请求的全部配置,包括请求的数据,可以对请求数据做校验和格式化请求数据
        axios.interceptors.request.use(function (config) {
            console.log('请求拦截器 成功-1')
            //throw "参数异常"
            //加入请求参数
            config.params = {id:2}
            return config;
        }, function (error) {
            //失败回调
            consolel.log("请求拦截器 失败-1")
            return Promise.reject(error);
        });

        axios.interceptors.request.use(function (config) {
            console.log('请求拦截器 成功-2')
            //throw "参数异常"
            //设置响应时间
            config.timeout = 2000
            return config;
        }, function (error) {
            consolel.log("请求拦截器 失败-2")
            return Promise.reject(error);
        });

        //添加一个响应拦截器,response为响应的数据,包括响应的数据,可以使用响应拦截器做返回数据的格式化
        axios.interceptors.response.use(function (response) {
            console.log('响应拦截器 成功-1')
            return response.data;
            //return response;
        }, function (error) {
            //失败回调
            console.log('响应拦截器 失败-1')
            return Promise.reject(error);
        });

        axios.interceptors.response.use(function (response) {
            console.log('响应拦截器 成功-2')
            return response;
        }, function (error) {
            //失败回调
            console.log('响应拦截器 失败-2')
            return Promise.reject(error);
        });
        //获取按钮 
        const btn = document.querySelectorAll('button');

        //发送ajax请求,类型为get
        btn[0].onclick = function() {
            axios({
                method: 'get',
                url: 'http://localhost:3000/posts',
            }).then(result => {
                console.log('最终结果如下:')
                console.log(result)
            }).catch(reason =>{
                console.log('异常结果如下:')
                console.log(reason)
            })
        }
    </script>
    
</body>
</html>

请求拦截器是后进先调用,响应拦截器是先进先调用。

如果请求拦截器-1中的请求出现异常,控制台打印结果如下:

在这里插入图片描述
到达请求拦截器-1抛出参数异常后,就会直接调用响应拦截器-1的失败回调方法,返回一个Promis对象后在调用响应拦截器-2的失败回调方法,最后给调用者捕获异常后输出异常信息。

四、axios取消请求

  1. 基本流程

    • 配置 cancelToken 对象

    • 缓存用于取消请求的 cancel 函数

    • 在后面特定时机调用 cancel 函数取消请求

    • 在错误回调中判断如果 error 是 cancel,做相应处理

  2. 实现功能

    • 点击按钮,取消某个正在请求中的请求
    • 连续点击请求按钮,判断请一个请求是否完成,未完成就取消,重新发请求
  3. json-serve配置响应的一个延时,便于取消请求,否则一发请求就立马响应,来不及取消请求,配置命令如下:

    • json-server db.json -d 2000
    • -d 2000:表示延迟响应2000ms
<!DOCTYPE html>
<html lang="en">
<head>
    <!-- 导入axios包 -->
    <link href="https://cdn.bootcdn.net/ajax/libs/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>
    <title>Axios基本使用</title>
</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 btn = document.querySelectorAll('button');
        //定义一个全局变量
        let cancel  = null;

        //发送ajax请求,类型为get
        btn[0].onclick = function() {
            if(cancel != null){
                //处理用户连续点击,服务器压力问题,每次先判断,之前的请求是否完成,没有就取消请求重新发送请求
                //取消上一次的请求
                cancel();
            }
            axios({
                method: 'get',
                url: 'http://localhost:3000/posts',
                //配置cancelToken对象,并给定义的全局变量赋值
                cancelToken: new axios.CancelToken(function(c){
                    cancel  = c;
                })
            }).then(result => {
                cancel  = null;
                console.log('最终结果如下:')
                console.log(result)
            })
        }
        //绑定取消点击事件
        btn[1].onclick = function(){
            //调用定义的全局变量的方法,名称要相同
            cancel();
        }
    </script>
    
</body>
</html>
/配置cancelToken对象,并给定义的全局变量赋值
                cancelToken: new axios.CancelToken(function(c){
                    cancel  = c;
                })
            }).then(result => {
                cancel  = null;
                console.log('最终结果如下:')
                console.log(result)
            })
        }
        //绑定取消点击事件
        btn[1].onclick = function(){
            //调用定义的全局变量的方法,名称要相同
            cancel();
        }
    </script>
    
</body>
</html>
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐