axios笔记

235 阅读6分钟

@TOC

Http 等介绍

在这里插入图片描述 Axios的特点

  • 基本promise的异步ajax请求库
  • 浏览器端/node端都可以使用
  • 支持请求/响应拦截器
  • 支持请求取消
  • 请求/响应数据转换
  • 批量发送多个请求

1.前后应用从浏览 器端向服务器发送HTTP请求(请求报文) 2.后台服务器接收到请求后,调度服务器应用处理请求,向浏览器端返回H响应(响应报文) 3.浏览器端接收到响应,解析显示响应体/调用监视回调

  • 其它的HTTP请求和响应笔记----》请求头和响应头的其它笔记

  • GET请求没有请求体

  • POST不携带数据也没有请求体

  • 配置对象是 属性名固定的

  • 区别一般http请求与ajax请求

    • ajax请求是一种特别的http请求
    • 2.对服务 器端来说,没有任何区别,区别在浏览器端
    • 3.浏览器端发请求:只有XHR或fetch发出的才是ajax请求,其它所有的都是,非ajax请求,
    • 4.浏览器 端接收到响应 (1)一般请求:浏览器--般会直接显示响应体数据,也就是我们常说的刷新/跳转页面. (2)ajax请求:浏览器不会对界面进行任何更新操作,只是调用监视的回调函数并传入响应相关数据

  1. 请求行 method url GET /product_ detail?id=2 POST /login

  2. 多个请求头 Host: www.baidu.com Cookie: BAIDUID=AD3B0FA706E; BIDUPSID=AD3BOFA706; Content Type: application/x-www-form-urlencoded或者application/json // 两种数据类型传输

  3. 请求体 username=tom&pwd= 123 第一种数据类型 {"username": "tom", "pwd": 123} 第二种数据类型

  4. 响应状态行: status statusText

  5. 多个响应头 Content-Type: text/html;charset=utf-8 Set-Cookie: BD CK SAM= 1;path=/

  6. 响应体 html文本/json文本/js/css/图片...


  • 响应状态字符串: 200 OK - 请求成功。一-般用于GET与POST请求 201 Created - 已创建.成功请求并创建了新的资源 401 Unauthorized - 未授权/请求要求用户的身份认证 404 Not Found - 服务器无法根据客户端的请求找到资源 500 Internal Server Error - 服务器内部错误,无法完成请求
  • 不同类型的请求方式: 1.GET:从服务器端读取数据 2.POST:向服务器端添加新数据 3.PUT:更新服务器端已经数据 4.DELETE:删除服务器端数据

服务成生成cookie数据返回给浏览器,再由请求头cookie拿到数据 POST 请求体参数格式:

  • Content Type: application/x-www-form-urlencoded;charset=utf-8 用于键值对参数,参数的键值用=连接,参数之间用&连接 例如: name=%E5%B0%8F%E6%98%8E&age= 12
  • Content-Type: application/json;charset=utf-8 用于json字符串参数 例如: {"name": "%E5%B0%8F%E6%98%8E", "age": 12}
  • Content-Type: multipart/form-data 用于文本上传的请求

查询参数 params 和 query / / 得到的是直接选择的对象:http://localhost:3000/posts/1? 得到的是过滤后的数组 : http://localhost:3000/posts/?id=1


  • API的分类
  1. REST API: restful (1) 发送请求进行CRUD哪个操作由请求方式来决定 (2) 同一个请求路径可以进行多个操作 (3 )请求方式会用到GET/POST/PUT/DELETE
  2. 非REST API: restless (1) 请求方式不决定请求的CRUD操作 (2) 一个请求路径只对应-一个操作. (3) 一般只有GET/POST

rest API 的接口创建 及介绍

API---> XMLHttpRequest 的MDN文档

  1. XMLHttpRequest(): 创建XHR对象的构造函数

  2. status: 响应状态码值,比如200, 404

  3. statusText: 响应状态文本

  4. readyState: 标识请求状态的只读属性(五个状态:数字) 0: 初始 1: open{)之后 2: send()之 后 3:请求中 4:请求完成

  5. onreadystatechange:绑定readyState改变的监听

  6. responseType:指定响应数据类型,如果是"json',得到响应后自动解析响应体数据

  7. response 响应体数据,类型取决于 response Type 的指定

  8. timeout 指定请求超时的时间 默认是 0 没限制

  9. ontimeout 绑定超时的监听

  10. onerror:绑定请求网络错误的监听

  11. open(): 初始化一个请求, 参数为: (method, urI[, async])

  12. send(data): 发送请求

  13. abort(): 中断请求

  14. getResponseHeader(name)获取指定名称的响应头值

  15. getAllResponseHeaders(): 获取所有响应头组成的字符串

  16. setRequestHeader(name, value):设置请求头


创建 rest API 接口rest API接口

  • npm下载 npm install -g json-server
  • 创建 db.json文件 (database文件)
  • 监听db.json文件 json-server --watch db.json 配置完成后可以进行案例的操作:

axios的CRUD案例操作

 <div>
        <button onclick="testGet()">GET请求</button>
        <button onclick="testPost()">POST请求</button>
        <button onclick="testPut()">PUT请求</button>
        <button onclick="testDelete()">DALETE请求</button>
    </div>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
    <script>
        function testGet() {
            // axios.get('http://localhost:3000/posts')
            // axios.get('http://localhost:3000/posts/1') // params 返回对应 数据 1 的对像
            axios.get('http://localhost:3000/posts/?id=1') // query 返回已筛选后的数组对象
            .then(response => {
                console.log('/posts get', response.data);
            });
        };

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

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

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

XML和Promise 封装简单的 Axios

<div>
        <button onclick="testGet()">GET请求</button>
        <button onclick="testPost()">POST请求</button>
        <button onclick="testPut()">PUT请求</button>
        <button onclick="testDelete()">DALETE请求</button>
    </div>
    <script>
        // 1. GET请求:从服务器端获取数据 
        function testGet() {
            axios({
                // url:'http://localhost:3000/posts',
                url:'http://localhost:3000/posts/1',
                method: "GET",
            }).then(response => {
                console.log('成功了!!');
                console.log(response);
            },error => {
                alert(error.message);
                console.log(error);
            });
        };

         // 2. POST请求:从服务器端添加/保存数据 
        function testPost() {
            axios({
                url:'http://localhost:3000/posts',
                method: "POST",
                parmas: {
                    id : "2",
                    name: "Liang"
                },
                data: {
                     "title": "json-server3",
                     "author": "typicode3"
                }
            }).then(response => {
                console.log('成功了!!');
                console.log(response);
            },error => {
                alert(error.message);
                console.log(error);
            });
        };

        // 3. PUT请求:从服务器端更新数据  传递 data 数据进行数据更新覆盖
        function testPut() {
            axios({
                url:'http://localhost:3000/posts/1',
                method: "put",
                parmas: {
                    id : "xuex",
                    name: "Liang"
                },
                data: {
                     "title": "json-server+++",
                     "author": "typicode+++"
                }
            }).then(response => {
                console.log('成功了!!');
                console.log(response);
            },error => {
                alert(error.message);
                console.log(error);
            });
        };

        // 4. Delete请求:从服务器端删除数据   转递 query参数进行删除
        function testDelete() {
            axios({
                url:'http://localhost:3000/posts/4',
                method: "delete",
            }).then(response => {
                console.log('成功了!!');
                console.log(response);
            },error => {
                alert(error.message);
                console.log(error);
            });
        };
        /* 
            1.函数的返回值为promise,成功的结果为response,异常的结果为error
            2.能处理多种类型的请求: GET/POST/PUT/DELETE
            3.函数的参数为一个配置对象
            {     
                url : '',  // 请求地址
                method: ' ', //请求方式GET/POST/PUT/DELETE
                params: {},  // GET/DELETE请求的query参数
                data: {},  // POST或DELETE请求的请求体参数
            }
            4.响应json数据自动解析为js 的对象 、 数组
        */
        function axios({url, method="GET", parmas={}, data={}}) {
            // 处理method(转换成大写)
            method = method.toUpperCase();
            // 处理query参数(并接到url上) id=1&xxx=as
            /* 
                {
                    id : 1,
                }
            */
           let queryString = '';
           Object.keys(parmas).forEach(key => {
               queryString += `${key}=${parmas[key]}&`;
           });
           if(queryString) {
            //    去除最后的&
                queryString = queryString.substring(0, queryString.length-1);
                // 接到url
                url += '?' + queryString;
           }
            // 返回一个Promise对象
            return new Promise((resolve, reject) => {
                // 1. 执行异步AJAX请求
                let xhr = new XMLHttpRequest();
                // 初始化,打开连接
                xhr.open(method, url, true);

                // 发送
                if(method === "GET" || method === "DELETE") {
                    xhr.send();
                }else if(method === "POST" || method === "PUT") {
                    xhr.setRequestHeader("Content-Type","application/json;charset=utf-8"); // 
                    xhr.send(JSON.stringify(data)); // 发送 JSON 格式的请求体参数
                }

                // 监听变化
                xhr.onreadystatechange = function() {
                    if(xhr.readyState !== 4) {
                        return; 
                    }else {
                            // 2.1 如果请求成功,调用resolve()
                            if(xhr.status >= 200 && xhr.status < 300) {
                                // 准备结果数据对象response
                                const response = {
                                        data : JSON.parse(xhr.response),
                                        status: xhr.status,
                                        statusText: xhr.statusText
                                }
                                resolve(response);
                            }else {
                            // 2.2 如果请求失败,调用reject()
                                reject(new Error('request error status is ' + status));   
                            }
                    }
                }

            });
        };
    </script>

Axios 的常用语法

  • axios(config):通用/最本质的发任意类型请求的方式
  • axios(urI[, config):可以只指定url发get请求
  • axios.request(config):等同于axios(config)
  • axios. get(urI[, config]):发get请求
  • axios.delete(url[, config]): 发delete请求
  • axios.post(urI[, data, config]):发post请求
  • axios.put(urI[, data, config]):发put请求

  • axios. defaults.xxx:请求的默认全局配置
  • axios.interceptors.request.use():添加请求拦截器
  • axios.interceptors.response.use():添加响应拦截器

  • axios.create([config]):创建一个 新的axios(它没有下面的功能)
    • 根据指定配置创建一个新的axios,也就就每个新axios都有自己的配置
    • 新axios只是没有取消请求和批量发请求的方法,其它所有语法都是一致的
    • 为什么要设计这个语法? (1) 需求:项目中有部分接口需要的配置与另一-部分接口需要的配置不太一样,如何处理 (2)解决:创建2个新axios,每个都有自己特有的配置,分别应用到不同要求的接口请求中

  • axios.Cancel():用于创建取消请求的错误对象
  • axios.CancelToken():用于创建取消请求的token对象
  • axios.isCancel():是否是-一个取消请求的错误
  • axios all(promises):用于批量执行多个异步请求
  • axios.spread(); 用来指定接收所有成功数据的回调函数方法

源码分析

  1. axios与Axios的关系? 1.从语法上来说: axios不是Axios的实例 2.从功能上来说: axios是Axios 的实例 3.axios 是Axios.prototype.request函数bind()返回的函数 4 axios 作为对象有Axios原型对象上的所有方法,有Axios对象上所有属性
  2. instance与axios的区别? 1.相同: (1)都是一个能发任意请求的函数: request(config) (2)都有发特定请求的各种方法: get()/post(/put()/delete() (3)都有默认配置和拦截器的属性: defaults/interceptors 2 不同 (1)默认匹配的值很可能不一样 (2) instance 没有axios 后面添加的一些方法:create() / CancelToken() / all()

base

 <div>
        <button onclick="testGet()">GET请求</button>
        <button onclick="testPost()">POST请求</button>
        <button onclick="testPut()">PUT请求</button>
        <button onclick="testDelete()">DALETE请求</button>
    </div>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
    <script>
        // axios.defaults.baseURL 指定默认配置
        axios.defaults.baseURL = 'http://localhost:3000';
        function testGet() {
            // axios.get('http://localhost:3000/posts/?id=1') // 返回已筛选后的数组对象
            axios({
                url: '/posts',
                params: {
                    id: 3
                }
            })
            .then(response => {
                console.log('/posts get', response.data);
            });
        };

        function testPost() {
            // axios.post('/posts', {"title": "json-server3", "author": "typicode3" }) 
            axios({
                url: '/posts',
                method: 'post',
                data: {"title": "json-server2", "author": "typicode2" }
            })
            .then(response => { // 添加 新的数据
                console.log('/posts post', response.data);
            });
        };

        function testPut() {
            // axios.put('http://localhost:3000/posts/3', {"title": "json-server...", "author": "typicode..." }) 
            axios({
                url: '/posts/3',
                method: 'put',
                data: {"title": "json-server3", "author": "typicode3" }
            })
            .then(response => { // 更新 3 的数据
                console.log('/posts put', response.data);
            });
        };

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

create

body>
    <!-- axios.create(config)
        * 根据指定配置创建一个新的axios,也就就每个新axios都有自己的配置
        * 新axios只是没有取消请求和批量发请求的方法,其它所有语法都是一致的
        *  为什么要设计这个语法?
            (1) 需求:项目中有部分接口需要的配置与另一-部分接口需要的配置不太一样,如何处理
            (2)解决:创建2个新axios,每个都有自己特有的配置,分别应用到不同要求的接口请求中
     -->
        <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>

        <script>
            axios.defaults.baseURL = 'http://localhost:3000';
            // 使用 axios 发送请求
            axios({
                url: '/posts', // 请求 3000
            });
           /*  axios({
                url: '/xxx',  // 请求 4000
            }); */

            const instance = axios.create({
                baseURL: 'http://localhost:4000'
            });

            // 使用 instance
           /*  instance({
                url: '/xxx', // 请求 4000
            }); */
            instance.get('/xxx');
        </script>

拦截器

<script>
        // 添加 请求拦截器 (回调函数)  后添加先执行
        axios.interceptors.request.use(config => {
            console.log('request interceptor1 onResolveed()');
            return config;
        }, error => {
            console.log('request interceptor1 onRejected()');
            return Promise.reject(error);
        });

        axios.interceptors.request.use(config => {
            console.log('request interceptor 2 onResolveed()');
            return config;
        }, error => {
            console.log('request interceptor 2 onRejected()');
            return Promise.reject(error);
        });

        // 添加 响应拦截器
        axios.interceptors.response.use(response => {
            console.log('response interceptor 1 onResolveed()');
            return response;
        },error => {
            console.log('response interceptor 1 onRejected()');
            return Promise.reject(error);
        });

         axios.interceptors.response.use(response => {
            console.log('response interceptor 2 onResolveed()');
            return response;
        },error => {
            console.log('response interceptor 2 onRejected()');
            return Promise.reject(error);
        });

         axios.get('http://localhost:3000/posts')
         .then(response => {
             console.log('data', response.data);
         })
         .catch(error => {
             console.log('error', error.message);
         });
        /*  相同的请求 响应拦截器 不同的自己处理 
        axios.get('http://localhost/posts')
         .then(response => {
             console.log('data', response.data);
         })
         .catch(error => {
             console.log('error', error.message);
         }); */

    </script>

取消请求 cancelToken

<body>
    <button onclick="getProducts1()">获取商品列表1</button>
    <button onclick="getProducts2()">获取商品列表2</button>
    <button onclick="cancelReq()">取消请求</button>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
    <script>

        let cancel; // 用于保存取消请求的函数

        function getProducts1() {
            // 在准备发送请求前,取消未完成的请求函数
            if(typeof cancel === 'function') {
                cancel();
            }
            axios({
                url : "http://localhost:4000/products1",
                cancelToken: new axios.CancelToken(function executor(c) { // c 是用于取消当前请求的函数 
                    // 保存取消函数,用于之后可能需要取消的当前请求
                    cancel = c;
                })
            }).then( response => {
                cancel = null;
                console.log('请求1成功了~~', response.data);
            },
            error => {  
                if(axios.isCancel(error)) {
                    // cancel = null;
                    console.log('请求1取消的错误~',error.message);
                }else { // 请求出错了~
                    cancel = null;
                    console.log('请求1失败了~~',error.message);
                }
            });
        };

        function getProducts2() {
             if(typeof cancel === 'function') {
                cancel();
            }
            axios({
                url : "http://localhost:4000/products2",
                cancelToken: new axios.CancelToken(function executor(c) { // c 是用于取消当前请求的函数 
                    // 保存取消函数,用于之后可能需要取消的当前请求
                    cancel = c;
                })
            }).then(response => {
                cancel = null;
                console.log('请求2成功了~~', response.data);
            },error => {
               if(axios.isCancel(error)) {
                    // cancel = null;
                    console.log('请求2取消的错误~',error.message);
                }else { // 请求出错了~
                    cancel = null;
                    console.log('请求2失败了~~',error.message);
                }
            });
        }

        function cancelReq() {
            // 执行强制取消请求的函数
            if(typeof cancel === "function") {
                cancel('强制取消请求~~~');
            }else {
                console.log('没有可取消的请求~');
            }
        }
    </script>
</body>

拦截器 和 取消请求结合

<body>
    <button onclick="getProducts1()">获取商品列表1</button>
    <button onclick="getProducts2()">获取商品列表2</button>
    <button onclick="cancelReq()">取消请求</button>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
    <script>

        // 添加请求拦截器
        axios.interceptors.request.use(config => {
            // 在准备发送请求前,取消未完成的请求函数
            if(typeof cancel === 'function') {
                cancel('取消请求~~');
            }
            // 添加 cancelToken的配置
             confdig.cancelToken =  new axios.CancelToken(function executor(c) { // c 是用于取消当前请求的函数 
                    // 保存取消函数,用于之后可能需要取消的当前请求
                    cancel = c;
            })
            return config;

        });

        // 添加响应拦截器
        axios.interceptors.response.use(
            response => {
                cancel = null;
                return response;
            },error => {
                if(axios.isCancel(error)) { // 取消请求的错误
                        // cancel = null;
                        console.log('请求1取消的错误~',error.message);
                        // 中断 Promise 链
                        return new Promise(() => {});
                    }else { // 请求出错了~
                        // cancel = null;
                        // 将错误向下传递
                        // throw error;
                        return Promise.reject(error);
                }
        });


        let cancel; // 用于保存取消请求的函数
        function getProducts1() {
            axios({
                url : "http://localhost:4000/products1",
            }).then( response => {
                console.log('请求1成功了~~', response.data);
            },
            error => {  // 只处理请求失败的情况,取消请求的错误的不同
               console.log('请求1失败了~',error.message);
            });
        };

        function getProducts2() {
            axios({
                url : "http://localhost:4000/products2",
            }).then(response => {
                console.log('请求2成功了~~', response.data);
            },error => {
                console.log('请求2失败了~~',error.message);
            });
        }

        function cancelReq() {
            // 执行强制取消请求的函数
            if(typeof cancel === "function") {
                cancel('强制取消请求~~~');
            }else {
                console.log('没有可取消的请求~');
            }
        }
    </script>