请求报文和响应报文包含的概念,原生Ajax的写法,get和pot的各种请求封装知识,防抖,节流

157 阅读2分钟

1.请求报文和响应报文

1651110679805.png

1.请求报文

1651111454165.png

2.响应报文

1651111906548.png

3.请求体

1651112616063.png

4.HTTP 响应码

2-3开头正常,4开头前端问题,5开头后端问题

1651112848708.png

5.HTTP 状态码

HTTP 状态码是公共的,业务状态码是公司自己定义的

查询地址:www.runoob.com/http/http-s…

1651113061211.png

XMLHttpRequest

1651115855484.png

2.Ajax-原生代码写法

就是不引入axios的原生写法,要自己加json转化对象

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
    <title>03-原生ajax.html</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
    </style>
</head>

<body>
    <script>
        // 1 创建 xhr对象
        const xhr = new XMLHttpRequest();
        // 2 调用 open方法 指定 请求类型,url
        xhr.open('get', 'http://www.itcbc.com:3006/api/getbooks');
        // 3 发送出去 send     发送Ajax(网络请求)
        xhr.send();
        // 4 监听onload  数据响应事件
        xhr.addEventListener('load', function () {
            // this
            console.log('数据回来啦');
            // console.log(this.response);
            // 字符串转对象
            const obj = JSON.parse(this.response);
            console.log(obj);
        });

//axios封装的写法
      // axios.get("http://www.itcbc.com:3006/api/getbooks")
      // .then(result)
    </script>
</body>

</html>

3.Ajax-get-原生代码携带参数写法

1651117794747.png

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        const xml = new XMLHttpRequest()
        //get原生代码携带参数写法
        xml.open('get', 'http://www.itcbc.com:3006/api/getbooks?appkey=lishupeng123&bookname=聂成林')
        xml.send()
        xml.addEventListener('load', function () {
           
            const obj = JSON.parse(this.response)
            console.log(obj);
        })
    </script>
</body>

</html>

4.content-type

类型格式

1651119194534.png

5.原生-post-携带参数

设置对应的 content-type才能显示对应的浏览器格式 xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xhr.send(query); // 传递 a=b&c=d

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>05-原生-post-携带参数.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
    </style>
  </head>
  <body>
    <!-- <form action="" enctype="application/x-www-form-urlencoded" ></form> -->
    <script>
      const xhr = new XMLHttpRequest();
      // open 来指定 请求方式
      xhr.open('post', 'http://www.itcbc.com:3006/api/addbook');
      // bookname: '从入门到精通',
      // author: '我自己',
      // publisher: '黑马出版社',
      // appkey : wanshao1234
      // post请求的参数 只能卸载 send()
      // post 三种不同数据格式的参数
      // 1 a=b&c=d   同时也需要指定 content-type 才行!!
      // 2 对象格式  {a:"b",c:"d"} 同时也需要指定 content-type 才行!!
      // 3 formdata 数据

      const data = {
        bookname: '1从入门到精通1',
        author: '我自己',
        publisher: '黑马出版社',
        appkey: 'wanshao1234',
      };
      // 把data 转成 a=b&c=d ....  URLSearchParams 
      const usp=new URLSearchParams(data);
      const query = usp.toString();
      
      // 设置对应的 content-type
      xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
      xhr.send(query); // 传递 a=b&c=d
      
      
      xhr.addEventListener('load', function () {
        console.log(this.response);
      });
    </script>
  </body>
</html>

6-原生-post-携带参数-json

要设置相应的 // 设置对应的 content-type才能显示对应的浏览器格式 xhr.setRequestHeader("Content-type", "application/json"); const str = JSON.stringify(data);

​ xhr.send(str); // 传递 a=b&c=d

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
    <title>06-原生-post-携带参数-json</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
    </style>
</head>

<body>
    <!-- <form action="" enctype="application/json" ></form> -->
    <script>
        const xhr = new XMLHttpRequest();
        xhr.open('post', 'http://www.itcbc.com:3006/api/addbook');

        // post 三种不同数据格式的参数
        // 1 a=b&c=d   同时也需要指定 content-type 才行!!
        // 2 对象格式  {a:"b",c:"d"} 同时也需要指定 content-type 才行!!
        // 3 formdata 数据

        const data = {
            bookname: '2从入门到精通2',
            author: '我自己',
            publisher: '黑马出版社',
            appkey: 'wanshao1234',
        };

        // 设置对应的 content-type
        xhr.setRequestHeader("Content-type", "application/json");
        const str = JSON.stringify(data);

        xhr.send(str); // 传递 a=b&c=d


        xhr.addEventListener('load', function () {
            console.log(this.response);
        });
    </script>
</body>

</html>

7-原生-post-携带参数-formdata

原生-post的参数是写xhr.send(formdata);里面的

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
    <title>07-原生-post-携带参数-formdata</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
    </style>
</head>

<body>
    <input type="file" accept="image/*" />
    <script>
        const input = document.querySelector('input');
        input.addEventListener('change', function () {

            const file = this.files[0];
            const formdata = new FormData();
            formdata.append('avatar', file);

            const xhr = new XMLHttpRequest();
            xhr.open('post', 'http://www.itcbc.com:3006/api/formdata');
            // 不用设置 content-type
            xhr.send(formdata);
            xhr.addEventListener('load', function () {
                console.log(this.response);
            });
        });
    </script>
</body>

</html>

8.ajax代码的封装

自己动手封装类似jq或者axios那种函数实现方法

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
    <title>08-ajax代码的封装.html</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
    </style>
</head>

<body>
    <script>
        /* 
        1 ajax  是一个函数(正解) 还是 一个对象 
        2 它接受一个 参数 格式  什么格式(对象)
        3 需要在ajax函数中 写完 整个原生ajax 发送请求的代码 
        
         */
        const option = {
            url: 'http://www.itcbc.com:3006/api/getbooks',
            type: 'get',
            data: 'appkey=wanshao1234',
            success(result) {
                // result 等于 要等于响应的数据 =  对象格式 
                console.log(result);
            },
        };

        // 里面方法   option.success(2);


        ajax(option);

        function ajax(config) {
            const xhr = new XMLHttpRequest();
            xhr.open(config.type, config.url + '?' + config.data);
            xhr.send();
            xhr.addEventListener('load', function () {
                //  响应的数据 this.response
                // console.log(this.response);
                const obj = JSON.parse(this.response)
                config.success(obj)
            });
        }
    </script>
</body>

</html>

9.ajax代码的封装.-get-不携带参数-优雅

用到了形参默认值和解构,让代码看的更简单一点

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
    <title>11-ajax代码的封装.-get-不携带参数-优雅.html</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
    </style>
</head>

<body>
    <script>
      // 形参默认值
      // 解构
      // function func(msg="hello") {
      //   console.log(msg);
      // }

      // func();// undefined
      // func();// 输出默认值
      // func('你好'); /// 你好

      // const option = {
      //   type: 'get',
      //   data: 'a=1',
      // };
      // const { data } = option;
      // console.log(data); // a=1

      // function func(config) {
      //   const {data}=config;
      //   console.log(data);
      // }
      // function func({ data = '1' ,type}) {
      //   // 解构 同时也设置了默认值
      //   // console.log(data);
      //   console.log(type);
      // }

      // func(option);

      const option = {
        url: 'http://www.itcbc.com:3006/api/getbooks',
        type: 'get',
        // data: 'appkey=wanshao1234',
        success(result) {
          console.log(result);
        },
      };

      ajax(option);

      ajax({
        url: 'http://www.itcbc.com:3006/api/getbooks',
        type: 'get',
        data: 'appkey=wanshao1234',
        success(result) {
          console.log(result);
        },
      });

      function ajax({ url, type, data = '', success }) {
        // 封装的时候考虑到用户 (可能带参数 , 可能不带参数)
        const xhr = new XMLHttpRequest();
        xhr.open(type, url + '?' + data);
        // 如果 data没有值  url =  http://www.itcbc.com?
        // 如果 data有值  url =  http://www.itcbc.com?appkey=wanshao1234
        xhr.send();
        xhr.addEventListener('load', function () {
          const obj = JSON.parse(this.response);
          success(obj);
        });
      }
    </script>
</body>
</html>

10.ajax代码的封装.-get-对象格式的参数

就是转化对象格式的要怎么转化

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
    <title>12-ajax代码的封装.-get-对象格式的参数</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
    </style>
</head>

<body>
    <script>
        // 1
        ajax({
            url: 'http://www.itcbc.com:3006/api/getbooks',
            type: 'get',
            // data: 'appkey=wanshao1234',
            success(result) {
                console.log(result);
            },
        });
        // 2
        ajax({
            url: 'http://www.itcbc.com:3006/api/getbooks',
            type: 'get',
            data: 'appkey=wanshao1234',
            success(result) {
                console.log(result);
            },
        });

        // 3
        ajax({
            url: 'http://www.itcbc.com:3006/api/getbooks',
            type: 'get',
            data: {
                appkey: 'wanshao1234',
                bookname: '今晚吃啥',
            },
            success(result) {
                console.log(result);
            },
        });

        function ajax({ url, type, data = '', success }) {
            const xhr = new XMLHttpRequest();

            if (typeof data === 'object') {
                // data是一个对象
                data = new URLSearchParams(data).toString();
            }
            // (typeof data === 'object')&&(data = new URLSearchParams(data).toString())
            xhr.open(type, url + '?' + data); // a=1&b=2 URLSearchParams
            xhr.send();
            xhr.addEventListener('load', function () {
                const obj = JSON.parse(this.response);
                success(obj);
            });
        }

      // typeof

      // console.log(typeof "" === 'object');  // 数据是不是对象格式
    </script>
</body>

</html>

11.ajax代码-post

判断请求参数是什么然后输出对应的代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
    <title>13-ajax代码-post.html</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
    </style>
</head>

<body>
    <script>
        ajax({
            url: 'http://www.itcbc.com:3006/api/getbooks',
            type: 'get',
            success(result) {
                console.log(result);
            },
        });
        ajax({
            url: 'http://www.itcbc.com:3006/api/getbooks',
            type: 'post',
            success(result) {
                console.log(result);
            },
        });
        function ajax({ url, type, data = '', success }) {
            const xhr = new XMLHttpRequest();
            // 判断 请求类型
            if (type === 'get') {
                // get请求的相关的代码
                if (typeof data === 'object') {
                    data = new URLSearchParams(data).toString();
                }
                xhr.open(type, url + '?' + data);
                xhr.send();
            } else if (type === 'post') {
                // post请求的相关的代码
                xhr.open(type, url);
                xhr.send();
            }
            xhr.addEventListener('load', function () {
                const obj = JSON.parse(this.response);
                success(obj);
            });
        }
    </script>
</body>

</html>

12.ajax代码-post-data传参

判断此时的data是什么类型的,然后解析出对应的代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
    <title>14-ajax代码-post-data传参</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
    </style>
</head>

<body>
    <input type="file" accept="image/*" />
    <script>
        /* 
        判断当前data的数据类型
        1 字符串类型 
                xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
                xhr.send(data); // 传递 a=b&c=d
        2 对象类型
                xhr.setRequestHeader("Content-type","application/json");
                const str =JSON.stringify(data);
                xhr.send(str); // 传递 a=b&c=d
        3 formdata
                xhr.send(formdata);
        
         */

        //  const data="a=1&c=1"
        //  const data={};

        // FormData 构造函数 (爸爸)
        // data 实例 (儿子)
        // const arr = new Array();
        // const data = new FormData();

        //  判断当前数据 字符串类型 typeof
        // console.log( typeof data === "string" ); // 字符串类型

        // console.log( typeof data === "object" ); // 对象类型

        // console.log(typeof data);

        // 判断你儿子 是不是亲生
        //  儿子   instanceof  爸爸
        //  实例   instanceof  构造函数
        // console.log( data instanceof FormData );
        // console.log(data instanceof Array);

        // ajax({
        //   url: 'http://www.itcbc.com:3006/api/addbook',
        //   type: 'post',
        //   data:"bookname=%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E7%B2%BE%E9%80%9A111&author=%E6%88%91%E8%87%AA%E5%B7%B1&publisher=%E9%BB%91%E9%A9%AC%E5%87%BA%E7%89%88%E7%A4%BE&appkey=wanshao1234",
        //   success(result) {
        //     console.log(result);
        //   },
        // });
        // ajax({
        //   url: 'http://www.itcbc.com:3006/api/addbook',
        //   type: 'post',
        //   data: {
        //     bookname: '从入门到精通222',
        //     author: '我自己',
        //     publisher: '黑马出版社',
        //     appkey: 'wanshao1234',
        //   },
        //   success(result) {
        //     console.log(result);
        //   },
        // });

        const input = document.querySelector('input');
        input.addEventListener('change', function () {
            const file = this.files[0];
            const formdata = new FormData();
            formdata.append('avatar', file);



            ajax({
                url: 'http://www.itcbc.com:3006/api/formdata',
                type: 'post',
                data: formdata,
                success(result) {
                    console.log(result);
                },
            });
        });

        function ajax({ url, type, data = '', success }) {
            const xhr = new XMLHttpRequest();
            // 判断 请求类型
            if (type === 'get') {
                // get请求的相关的代码
                if (typeof data === 'object') {
                    data = new URLSearchParams(data).toString();
                }
                xhr.open(type, url + '?' + data);
                xhr.send();
            } else if (type === 'post') {
                // post请求的相关的代码
                xhr.open(type, url);

                // 判断是不是字符串
                if (typeof data === 'string') {
                    xhr.setRequestHeader(
                        'Content-type',
                        'application/x-www-form-urlencoded'
                    );
                    xhr.send(data);
                } else if (typeof data === 'object') {
                    // 判断是不是对象

                    // 判断是不是 FormData 实例
                    if (data instanceof FormData) {
                        // 是 FormData 实例
                        xhr.send(data);
                    } else {
                        // 普通的对象
                        xhr.setRequestHeader('Content-type', 'application/json');
                        const str = JSON.stringify(data);
                        xhr.send(str); // 传递 a=b&c=d
                    }
                }
            }
            xhr.addEventListener('load', function () {
                const obj = JSON.parse(this.response);
                success(obj);
            });
        }
    </script>
</body>

</html>

13.防抖

就是输入框不会输一个字发送一次请求,原理就是设一个延时器和清除延时器实现对应的功能

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
    <title>15-防抖</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        table {
            width: 1000px;
            margin: 0 auto;
        }

        thead tr {
            background-color: blue;
            color: #fff;
            font-size: 20px;
        }

        tbody tr:nth-child(odd) {
            background-color: green;
            color: #fff;
            font-size: 18px;
        }

        tbody tr:nth-child(even) {
            background-color: peru;
            color: #fff;
            font-size: 18px;
        }

        td,
        th {
            padding: 10px;
        }

        input {
            width: 1000px;
            display: block;
            margin: 30px auto;
            height: 100px;
            border-radius: 50px;
            border: none;
            background-color: skyblue;
            font-size: 40px;
            text-indent: 20px;
            color: #666;
            outline: none;
        }
    </style>
</head>

<body>
    <input type="text" />
    <table>
        <thead>
            <tr>
                <th>id</th>
                <th>书名</th>
                <th>作者</th>
                <th>出版社</th>
            </tr>
        </thead>
        <tbody></tbody>
    </table>
    <script src="../lib/axios.js"></script>
    <script>
        /* 
        防抖  防止抖动
        1 用在输入框中 实现 不用用户按下回车键 就发送请求
        2 技术原理
          1 用新的一次输入来清除上一次的延时器 
          2 同时开启一个新的延时器 
        
         */
        getData();
        // change事件  输入框的值发生改变-输入框失去焦点 才触发
        // input 事件

        // 定义一个 演示器 id
        // let timeid; // 钻 石 城 堡

        const input = document.querySelector('input');
        // input.addEventListener('input', function (event) {
        //     clearTimeout(timeid);
        //     // 开启了一个延时器 里面代码 1s后会执行
        //     timeid = setTimeout(function () {

        //     }, 1000);
        // });
        let time;
        input.addEventListener('input', function (even) {
            clearTimeout(time)
            time = setTimeout(() => {
                const value = input.value.trim();
                const queryStr = `?bookname=${value}`;
                getData(queryStr);

            }, 1000);

        })


        function getData(query = '') {
            axios({
                method: 'get',
                url: 'http://www.itcbc.com:3006/api/getbooks' + query,
                // params:{},
            }).then((result) => {
                console.log(result);
                const arr = result.data.data;
                render(arr);
            });
        }

        function render(arr) {
            let html = arr
                .map(
                    (value) => `
      <tr>
          <td>${value.id}</td>
          <td>${value.bookname}</td>
          <td>${value.author}</td>
          <td>${value.publisher}</td>
        </tr>
      `
                )
                .join('');
            document.querySelector('tbody').innerHTML = html;
        }
    </script>
</body>

</html>

14.节流

上一次的业务没有结束的话 不允许开启下一次业务,两种实现方法,一是经验按钮,二是起一个变量来判断

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
    <title>16-节流.html</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
    </style>
</head>

<body>
    <button>获取数据</button>
    <script src="../lib/axios.js"></script>
    <script>
        /* 
        节流
        上一次的业务没有结束的话 不允许开启下一次业务
        使用场景 移动端分页  -  倒计时按钮 等等 
        
         */



        // 这一次请求还没有结束 就不能开启下一个请求
        // 业务 分页 业务

        // 开关
        let isLoadding = false; // 有没有请求在发送当中

        // 点击按钮的时候先判断 isLoadding true还是false
        //  true 请求在发送中  return
        //  false 没有请求
        //   先设置 isLoadding true
        //   发送请求出去
        //  请求回来了  设置 isLoadding = false

        document.querySelector('button').addEventListener('click', function () {
            if (isLoadding) {
                return;
            }

            isLoadding = true;

            // 发送请求的时候  禁用按钮
            // this.disabled=true;
            getData();
        });
        function getData(query = '') {
            console.log('请求发送出去');
            axios({
                method: 'get',
                url: 'http://www.itcbc.com:3006/api/getbooks' + query,
                // params:{},
            }).then((result) => {
                console.log('数据回来了');
                // document.querySelector('button').disabled=false
                isLoadding = false;
            });
        }
    </script>
</body>

</html>