Ajax增删改查--封装JS-接口文档-network调试工具-from表单-原生ajax.XML代码

267 阅读18分钟

01-Ajax-概念-请求方式

1-服务器相关的基础概念

服务器

服务器的本质:也是一台电脑

服务器的作用:

存储一个网站的文件(HTML、CSS、JS、图片、音乐.....)
 提供网站的文件给用户

资源:

  1. 服务器上的 网页(html文件)、图片、音乐、视频、字体文件、CSS文件、JS文件等等都称之为资源。所以资 源1代指服务器上存储的内容。

  2. 通俗的讲,我们浏览网页时,从网络当中看到的内容都叫做资源。

  3. 数据也是资源 网页中的数据,也是服务器对外提供的一种资源。例如股票数据、各行业排行榜等。

  4. 服务器多数情况都使用数据表的方式来存储数据,和我们平时见到的表格差不多,形式如下

    1650810451290

客户端

概念在前端开发中,客户端特指“Web 浏览器”。 作用将互联网世界中的 Web 资源加载、并呈现到浏览器窗口中供用户使用

请大家例举最常见的“客户端浏览器”都有哪些:

Chrome 浏览器 (谷歌) FireFox 浏览器(火狐) Edge 浏览器(IE) Safari 浏览器 (苹果)

URL 地址 (统一资源定位符)

生活中的地址,表示地球上的一个确切的地理位置 URL 地址,表示服务器上每个资源的确切位置。

服务器上的每个资源,都对应着独一无二的URL地址

数据也是服务器上的资源 对数据的操作(增删改查),也对应着不同的URL地址

1650811977564

客户端与服务器通信的过程:

客户端与服务器之间的通信过程,分为请求 - 响应两个步骤。

其中:

1 请求的概念:客户端通过网络去找服务器要资源的过程,叫做“请求” 2 响应的概念:服务器把资源通过网络发送给客户端的过程,叫做“响应”

什么是Ajax?

思考:数据对于一个网页来说重不重要? 答案:非常重要!数据是网页的灵魂!!!离开数据之后,哪怕这个网页做的再漂亮,也没有实际的作用。

既然数据对于网页这么重要,请问大家,在网页中如何使用服务器的数据? 答案:需要用到的技术:Ajax

Ajax 是浏览器中的技术:用来实现客户端网页请求服务器的数据。 它的英文全称是 Asynchronous Javascript And XML,简称 Ajax。

1650812375671

Ajax :

一种使用JS来异步获取XML格式 数据的 技术

异步 JS and XML

结论:网页中 Ajax 的应用场景无处不在,有数据的地方就有 Ajax!

同步代码:

1 代码是执行了,但是结果会马上得到

2 按顺序一件一件做事

异步代码:

1 代码是执行了,不能马上得到结果 延迟一点来执行

2 不一定按照正常上下顺序来执行代码 - 同时进行

3 异步代码 定时器和延时器

     /* 
    异步  
      1 代码是执行, 但是结果不会马上得到
        1 你寄出一封信  信 马上到 目的人手中
        2 你妈妈出门喊你回家吃饭,  你马上就回到家了
        3 你刚刚做上出租车, 你马上到家了? 
      2 可以同时做多件事
        1 你现在再大街上 和 三个大妈在吵架 
          每一个人 同时在输出 -  你先骂我 -  你骂我了 
          
    同步
      1 代码是执行了,但是结果会马上得到
        1 你同桌 给你一拳  马上就会感觉到痛 
        2 饮水机大水 一按下按键 水出来
        3 你现在把你加 电源开关关掉 立马就断网 
      2 按顺序一件一件做事 
        1 核酸检查 
          排队的一个人一个人在进行 
     */

      //  同步的代码 (以前学过的程序 绝大部分都是同步的代码 按顺序-马上得出结果)

      // console.log( document.querySelector("body") ); // 1 有body
      // console.log( document.querySelector("div") ); // 2  没div

      // 异步的代码   顺序 -
      // 定时器和延时器
      // console.log(1);
      // setTimeout(() => {
      //   console.log('延时器');
      // }, 0);
      // console.log(3);
      setInterval(() => {
        document.querySelector('h1').innerText = Date.now();
      }, 10);

      setInterval(() => {
        document.querySelector('h2').innerText = Date.now();
      }, 10);


      /* 
      异步代码
      1 代码是执行了,不能马上得到结果    延迟一点来执行 
      2 不一定按照正常上下顺序来执行代码 - 同时进行 
      3 异步代码  定时器和延时器 
      
       */

2-Ajax有5种请求方式

Ajax中,客户端浏览器在请求服务器上的数据时,根据操作性质(增删改查)的不同,可以分为以下 5 种常见的操作

1650886219158

1- get 请求

GET 请求用于从服务器获取数据

1650886269780

2-post 请求

POST 请求用于向服务器新增数据:

1650886334180

3-delete 请求

DELETE 请求用于删除服务器上的数据

1650886376485

4-put 请求

PUT 请求用于更新服务器上的数据(侧重于完整更新:例如更新用户的完整信息)

1650886497143

5-patch 请求

PATCH 请求用于更新服务器上的数据(侧重于部分更新:例如只更新用户的手机号):

1650886465747

操作服务器上的数据除了要使用 URL地址,还需要指定的请求方式

操作服务器上的数据时:

获取服务器上的数据,需要使用 get 获取方式

新增(添加)数据,需要使用 post 添加方式

删除数据,需要使用 新)数据,需要使用 delete 删除方式

完整修改(更新)数据,需要使用 put 全修改方式

修改(更新)部分数据,需要使用 patch 部分修改方式

3-axios基础用法

要使用axios的JS,就要去官网下载对应的JS文件,在引入

1650888971159

公式:

axios( { 
method : ' 请求类型 '
url: ' 资源地址 '
  }) . then ( 参数 ){     

//then 固定!! 是axios封装的一个代码  意思 服务器把数据返回了,then里面的代码就会被触发
console.log( 参数 ); // 服务器给我们返回的数据!
}

代码示例:

<!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>02-第一次获取服务器上的数据.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
    </style>
  </head>
  <body>
    <table>
      <thead>
        <tr>
          <th>id</th>
          <th>书名</th>
          <th>作者</th>
          <th>出版社</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>
    <!-- 1 引入axios -->
    <script src="./lib/axios.js"></script>
    <script>
      /* 
      想要获取服务器上的数据 url ,它是后端程序员提供  
      http://www.itcbc.com:3006/api/getbooks  图书数据 

      我们需要通过代码的方式  把服务器上的数据 变成 一个普通的变量 数组
      给我数组了 我就懂得如何去页面渲染了  第三方的一个js的帮助 

      axios
      1 下载 引入到项目中
      2 根据url的地址 来编写代码 
        1 获取数据 -get   ( 请求类型  1  get 2 post 3 delete  4 put 5 patch  )
        2 编写代码
       */

      //  开始向服务器 发送请求 索要数据
      axios({
        //  method:"请求类型",
        //  url:"资源地址",
        method: 'get',
        url: 'http://www.itcbc.com:3006/api/getbooks',
      }).then((result) => {
        //  then 固定!! 是axios封装的一个代码  意思 服务器把数据返回了,then里面的代码就会被触发
        // console.log(result); // 服务器给我们返回的数据!!
        // 数组数据

        // 给你了一个数组 arr 数组的格式
        const arr = result.data.data; // 字段的名称 id、bookname、author。publisher 固定
        // console.log(arr);
        // 你 有能力 根据 数组 来 显示到页面中

        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>

关于 get 的其他指定方式-多个参数指定

请求参数 固定语法 params

代码示例:

<!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>
    <style>
      table {
        border-collapse: collapse;
      }
      th,
      td {
        text-align: center;
        padding: 10px 20px;
      }
    </style>
  </head>
  <body>
    <table border="1">
      <thead>
        <tr>
          <th>id</th>
          <th>书名</th>
          <th>作者</th>
          <th>出版社</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>
    <!--  1 引入 JS -->
    <script src="./lib/axios.js"></script>
    <script>
      axios({
        //发送请求类型
        method: "get",
        //服务器地址
        url: "http://www.itcbc.com:3006/api/getbooks",
        //请求参数 固定语法 params
        params: {
          //可以指定多个参数,但是那数据要同时满足多个条件才行
          id: 5913,
          bookname: "Web开发实战",
          // 0 条数据 多个参数的含义是 && 两个条件都要满足 不是 || 或者
          // id  === 5913 && 书名 === 万少
          // id: 5913,
          // bookname: '万少',
        },

        // .then  是固定语法
      }).then((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>

关于 get 的其他指定方式-拼接参数

直接在 url 地址上拼接 ?属性名=属性值&属性名=属性值

      axios({
        method: 'get',
        url: 'http://www.itcbc.com:3006/api/getbooks',
        params: { // 推荐直观 
          id: 5913,
          bookname: 万少,
        },
        // url: 'http://www.itcbc.com:3006/api/getbooks?id=5913',
        // url: 'http://www.itcbc.com:3006/api/getbooks?bookname=万少',
        // url: 'http://www.itcbc.com:3006/api/getbooks?bookname=万少&id=5913',// ?属性名=属性值&属性名=属性值
      }).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;
      }

02-Ajax增删改查-请求方式使用详情-弹出框-封装JS-接口文档-network调试工具

1- get 获取请求 携带参数-params

get 获取请求方式 带有固定参数

请求类型: method : 'get'

参数: params : { 属性名 : 属性值 }

GET 请求的查询参数

如果想指定查询的条件,可以通过 params 选项来指定查询的参数:

在 GET 请求中携带多个查询参数

如果要携带多个参数,只需要在 params 对象中指定多个查询参数项即可

1 在实际开发过程种,我们可以在前端 指定参数来查询对应的数据

2 指定参数的 参数的代码写法 必须要写在

params 对象中,以 键值对的形式存在

3 params 对象中,写什么样的键值对 规定要由后端来决定 前端不懂的时候问他

get的获取时代有参数的,而你要获取什么数据 就在 参数里面填写 如果有多个 请求个体 就填写多个 ,数据库中有这个数据就会打印出来

1650889132491

注意: 地址后缀不同 api/getbooks

url: "www.itcbc.com:3006/api/getbook…"

代码是列:

<!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>
    <style>
      table {
        border-collapse: collapse;
      }
      th,
      td {
        text-align: center;
        padding: 10px 20px;
      }
    </style>
  </head>
  <body>
    <table border="1">
      <thead>
        <tr>
          <th>id</th>
          <th>书名</th>
          <th>作者</th>
          <th>出版社</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>
    <!--  1 引入 JS -->
    <script src="./lib/axios.js"></script>
    <script>
      /* 
    小结
    1 在实际开发过程种,我们可以在前端 指定参数来查询对应的数据 
    2 指定参数的 参数的代码写法 必须要写在
      params 对象中,以 键值对的形式存在
    3 params 对象中,写什么样的键值对 规定要由后端来决定  前端不懂的时候问他

       */
      axios({
        //发送请求类型
        method: "get",
        //服务器地址
        url: "http://www.itcbc.com:3006/api/getbooks",
        //请求参数 固定语法 params
        params: {
          //键值对   是需要问后端程序员才知道
          //   id: 5913,  //后端就会返回 id为 5913的那一条数据
          // bookname:"万少"// 后端就会返回 书名 为 万少的一堆数据
          bookname: 11,
        },

        // .then  是固定语法
      }).then((result) => {
        //  获取对象里面的数组
        const arr = result.data.data; // 字段的名称 id、bookname、author。publisher 固定
        // 调用函数  里面要传参数  不然函数拿不到数组
        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>

2-post 新增请求 携带参数-data

使用 axios 发起 POST 请求时,只需要将 method 属性的值设置为 'POST' ,URL地址改为 '/api/addbook':

请求类型 method : 'post'

参数: data : { 属性名 : 属性值 }

注意: 地址后缀不同 /api/addbook

url: 'www.itcbc.com:3006/api/addbook'

代码示例:

<!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-post案例</title>

    <style>
      body {
        height: 100vh;
        display: flex;
        justify-content: space-around;
      }
      .left {
        width: 1000px;
      }
      .right {
        flex: 1;
      }
      form {
        width: 90%;
        margin: 0 auto;
        background-color: #eee;
      }
      h3 {
        background-color: brown;
        color: #fff;
        padding: 10px;
      }
      input {
        display: block;
        width: 80%;
        margin: 10px auto;
        height: 50px;
        border-radius: 5px;
        font-size: 25px;
        color: #666;
      }
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      table {
        width: 800px;
        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: 800px;
        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>
    <div class="left">
      <input type="text" class="keyword" />
      <table>
        <thead>
          <tr>
            <th>id</th>
            <th>书名</th>
            <th>作者</th>
            <th>出版社</th>
          </tr>
        </thead>
        <tbody></tbody>
      </table>
    </div>
    <div class="right">
      <form>
        <h3>添加</h3>
        <input type="text" placeholder="书名" class="bookname" />
        <input type="text" placeholder="作者" class="author" />
        <input type="text" placeholder="出版社" class="publisher" />
        <input type="button" value="新增" class="btnadd" />
      </form>
    </div>
    <!-- 1 引入axios -->
    <script src="./lib/axios.js"></script>
    <script>
      getData();

      const keyword = document.querySelector('.keyword');
      const booknameDom = document.querySelector('.bookname');
      const authorDom = document.querySelector('.author');
      const publisherDom = document.querySelector('.publisher');
      const btnaddDom = document.querySelector('.btnadd');

      keyword.addEventListener('keydown', function (event) {
        if (event.key === 'Enter') {
          const value = this.value.trim();
          if (value) {
            console.log('不是空字符串');
            const queryStr = `?bookname=${value}`;
            getData(queryStr); // 把参数带过去
          } else {
            getData();
          }
        }
      });

      btnaddDom.addEventListener('click', function () {
        // 1 获取三个输入框的值
        const bookname = booknameDom.value;
        const author = authorDom.value;
        const publisher = publisherDom.value;

        // 2 拼接 post请求要的参数
        const data = {
          // 对象简写
          bookname,
          author,
          publisher,
        };
        // 3  发送post请求 来完成新增数据
        axios({
          method: 'post',
          url: 'http://www.itcbc.com:3006/api/addbook', // url
          // data:data,// es6 对象简写的知识
          data, // es6 对象简写的知识
        }).then((result) => {
          console.log(result);
          // 调用一次 getData
          getData();
          // 重置表单
          booknameDom.value = '';
          authorDom.value = '';
          publisherDom.value = '';
        });
      });

      // 封装使用ajax来获取数据的函数
      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>

3-delete 删除请求 携带参数-params

请求类型: method : 'delete'

参数: params : { ID : 属性值 } 要使用删除 id 是必须要有

参照接口文档,发现删除图书,需要使用必填的id参数。

循环遍历数据时,将id值存储到 删除按钮的 自定义属性(data-id)中 单击 删除 按钮时,获取自定义属性data-id的值,这个值就是id

注意: 地址后缀不同 /api/delbook

url: http://www.itcbc.com:3006/api/delbook

代码示例:

<!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-图书管理-删除-确认框</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>
          <th>操作</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>
    <script src="./lib/axios.js"></script>
    <script>
      const tbody = document.querySelector("tbody");
      //打开页面渲染
      getData();

      //委托点击  删除
      tbody.addEventListener("click", function (event) {
        if (event.target.className === "del") {
          // 判断用户是否确定删除
          if (!confirm("您确定删除吗")) {
            // 不删除
            return; // 不再往下执行代码
          }

          //  获取a标签对应的id 自定义属性
          const { id } = event.target.dataset;//简写
          // 根据接口文档的要求 组装代码
          axios({
            url: "http://www.itcbc.com:3006/api/delbook",
            method: "delete",
            params: { id },//简写
          }).then((result) => {
            console.log(result);
            getData(); // 删除成功了 重新显示页面数据
          });
        }
      });

      //Ajax 封装
      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>
          <td><a data-id="${value.id}" class="del" href="javascript:;">删除</a> </td>
        </tr>
      `
          )
          .join("");
        document.querySelector("tbody").innerHTML = html;
      }
    </script>
  </body>
</html>

4-put 修改请求-data

请求类型: method: 'put'

参数: data : { 属性名 : 属性值 }

注意: 地址后缀不同 /api/updatebook

url: "www.itcbc.com:3006/api/updateb…"

代码示例:

<!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-post案例</title>

    <style>
      body {
        height: 100vh;
        display: flex;
        justify-content: space-around;
      }
      .left {
        width: 1000px;
      }
      .right {
        flex: 1;
      }
      form {
        width: 90%;
        margin: 0 auto;
        background-color: #eee;
      }
      h3 {
        background-color: brown;
        color: #fff;
        padding: 10px;
      }
      input {
        display: block;
        width: 80%;
        margin: 10px auto;
        height: 50px;
        border-radius: 5px;
        font-size: 25px;
        color: #666;
      }
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      table {
        width: 800px;
        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: 800px;
        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>
    <div class="left">
      <input type="text" class="keyword" />
      <table>
        <thead>
          <tr>
            <th>id</th>
            <th>书名</th>
            <th>作者</th>
            <th>出版社</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody></tbody>
      </table>
    </div>
    <div class="right">
      <form>
        <h3>编辑</h3>
        <input type="text" placeholder="书名" class="bookname" />
        <input type="text" placeholder="作者" class="author" />
        <input type="text" placeholder="出版社" class="publisher" />
        <input type="button" value="编辑" class="btnadd" />
      </form>
    </div>
    <!-- 1 引入axios -->
    <script src="./lib/axios.js"></script>
    <script>
      const tbody = document.querySelector("tbody");
      //全局变量
      let arr;
      let id;

      getData();
      const keyword = document.querySelector(".keyword");
      const booknameDom = document.querySelector(".bookname");
      const authorDom = document.querySelector(".author");
      const publisherDom = document.querySelector(".publisher");
      const btnaddDom = document.querySelector(".btnadd");

      //事件委托  点击编辑
      tbody.addEventListener("click", function (e) {
        if (e.target.className === "editbtn") {
          //获取 a 自定义下标  解构方法
          let { index } = e.target.dataset;
          //获取另一个方法中的数组
          console.log(arr[index]);
          //把对应的数据显示在表单中
          booknameDom.value = arr[index].bookname;
          authorDom.value = arr[index].author;
          publisherDom.value = arr[index].publisher;
          //获取 id
          id = arr[index].id;
          console.log(id);
        }
      });

      //点击编辑按钮  把新修改的数据 从新放进数据中
      btnaddDom.addEventListener("click", function () {
          //获取表单的值
        let data = {
          bookname: booknameDom.value,
          author: authorDom.value,
          publisher: publisherDom.value,
          id: id,
          //要加上自己的密码
          appkey: "pengy123",
        };
        // 发送一个编辑请求
        axios({
          method: "put",
          url: "http://www.itcbc.com:3006/api/updatebook",
          // query - params
          // body - data   是相同的
          data,
        }).then((seult) => {
          console.log(seult);
          //编辑成功  重新调用数据 渲染表格
          getData();
        });
      });

      // 封装使用ajax来获取数据的函数
      function getData(query = "") {
        axios({
          method: "get",
          url: "http://www.itcbc.com:3006/api/getbooks" + query,
          params: {
            appkey: "pengy123",
          },
        }).then((result) => {
        //   console.log(result);
          arr = result.data.data;
          let html = arr
            .map((value, index) => {
              return `
      <tr>
          <td>${value.id}</td>
          <td>${value.bookname}</td>
          <td>${value.author}</td>
          <td>${value.publisher}</td>
          <td> <a href="javascript:;" class="editbtn" data-index='${index}'>编辑</a></td>
        </tr>
      `;
            })
            .join("");
          tbody.innerHTML = html;
        });
      }
    </script>
  </body>
</html>

5-弹出框-confirm

​ confirm js中自带 确认框

​ 如果用户点击 确定 返回true 点击 取消 - false

​ confirm("您舍得删除吗😶")

      document.querySelector('button').addEventListener('click', function () {
        if (confirm('您舍得删除吗😶')) {
          //
          console.log('可以执行删除');
        } else {
          console.log('取消删除');
        }
      });

6-快速获取from表单所有数据-封装JS

封装JS:

给 from表单中的 input 添加 name 属性 让后利用 input[name] 获取 dom元素伪数组

伪数组 用forEach循环 装进一个空对象中 必须要 return 返回对象

再创建一个 JS 文件 放这个封装函数进去

1650890649457

JS使用:

1650890831062

代码示例:

<!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-快速获取到form表单所有数据.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      input[name] {
        /* <input type="text" name="username" /> */
        /* 表示选择到了 有name属性的input标签 */
        background-color: red;
      }
    </style>
  </head>
  <body>
    <form class="f1">
      <input value="111" type="text" name="username" />
      <input value="222" type="text" name="password" />
      <input value="333" type="text" name="address" />
      <input value="444" type="text" name="phone" />
      <input type="text" />
      <input type="text" />
      <input type="text" />
      <button type="button">注册数据</button>
    </form>

    <form class="f2" action="">
      <input type="text" name="nickname" value="aabbcc" />
    </form>
    <script>
      // 获取表单1 数据 对象格式
      const obj1 = getForm('.f1');
      // 获取表单2 数据 对象格式
      const obj2 = getForm('.f2');

      console.log(obj1);
      console.log(obj2);

      // query 只能传入 form标签的选择器
      function getForm(query) { // 在定义函数的时候写形参 - 名字都可以随意改 
        const inputs = document.querySelectorAll(query + ' input[name]');
        // const inputs = document.querySelectorAll('.f1 input[name]');
        const obj = {};
        inputs.forEach((dom) => {
          obj[dom.name] = dom.value;
        });

        return obj;
      }
    </script>
  </body>
</html>

7-接口文档

使用 Ajax 请求数据时,被请求的 URL 地址,就叫做数据接口(简称:接口或 API 接口)。

同时,每个接口必须有对应的请求方式。例如:

www.itcbc.com:3006/api/getbook… 获取图书列表的接口(GET 请求) http://www. itcbc.com:3006/api/addbook 添加图书的接口(POST 请求)

接口文档就是接口的使用说明书,它是我们调用接口的依据。

而这个接口文档是由后端程序员编写

注意:容易出错的地方

1650891258718

接口文档 各种说明

1650891191538

8-network-调试工具

1

1650891612035

2

1650891664411

3

1650891669773

9-关于图书增加密码-appkey

只能自己修改数据,别人用不了,给参数添加个密码 键 与 值

公式: appkey : '自己设置的密码'

只有在参数上填写正确的密码 才会获取到对应的数据

         //添加
			// 参数
          data: {
            bookname: '你们能看到吗',
            author: '我自己',
            publisher: '黑马出版社',
            // 名字 appkey 
            // 6-12 任意字符 不要别人知道
            appkey:"pengy123"
          },
            
           //获取
          method: 'get',
          url: 'http://www.itcbc.com:3006/api/getbooks' + query,
          params:{
            appkey:"pengy123"
          }

03-from表单-axios简写-JS内置对象-文件上传-拦截器

1-from表单的组成-旧方式使用

网页中采集数据的表单由三个部分组成,分别是:表单标签 表单域 表单按钮

表单标签就是指 from 标签 它是一个容器 用来在网页上指定的区域划定为 表单区域

而表单域是提供了采集用户信息的渠道 , 常见的表单域有 input、textarea、select 等。

注意: 每个表单域必须包含 name 属性,否则用户填写的信息无法被采集到

当表单数据填写完毕后,用户点击表单按钮,会触发表单的提交操作,从而把采集到的数据提交给服务器。

注意:

< button type='submit'>按钮

type="submit" 表示提交按钮的意思 type 属性的默认值就是 submit,因此 type="submit" 可以省略不写

标签最重要的 3 个属性分别是 action、method 和 enctype。简介信息如下表所示:
属性可选值说明
action接口的 url 地址把表单采集到的数据,提交到哪个接口中
methodGET 或 POST数据的提交方式(默认值为 GET)
enctypeapplication/x-www-form-urlencoded multipart/form-data text/plain(很少用)数据的编码格式。具体指的是:把表单数据提交给服务器之前,如何对将要提交的数据进行编码 (默认值 application/x-www-form-urlencoded)

注意:enctype 属性只能搭配 POST 提交方式一起使用;如果是 GET 提交,则 enctype 没有意义

早期form表单提交数据 了解

以 get 方式提交表单

  旧方式 提交数据 form标签的方式 提交
  1 肯定会出现 刷新页面 调整页面的情况 (体验! 很糟糕)
  2 输入框没name属性 没有把数据 提交给到后端

在 标签上,通过 action 属性指定提交的 URL 地址,通过 method 属性指定提交的方式为 GET:

<body>
    <!-- 
      旧方式 提交数据 form标签的方式 提交
      1 肯定会出现 刷新页面 调整页面的情况 (体验! 很糟糕)
      2 输入框没name属性 没有把数据 提交给到后端

      新的方式 ajax 
      1 异步 网络请求 (异步 同时执行多个事情 - 你一边正在使用网页功能而且数据提交 同时进行(整个网页 ))
      2 规范  只要写到input标签想要数据提交 习惯的加上 name属性
        如果使用ajax的技术来提交数据  是完全不给标签添加name属性 
      3 习惯下来  form input标签name 都一直在使用   
      
     -->
    <form action="http://www.itcbc.com:3006/api/getbooks" method="get">
      <div>
        <label for="">用户名</label>
        <input type="text" name="username">
      </div>
      <div>
        <label for="">密码</label>
        <input type="text" name="password">
      </div>
      <div>
        <label for="">随便的测试</label>
        <input type="text">
      </div>
      <!-- <button type="submit">提交</button> -->
      <button >提交</button>
    </form>
  </body>

注意:由于 method 属性的默认值就是 GET,因此上述的 method="GET" 可以被省略!

以post 方式提交表单数据

在 标签上,通过 action 属性指定提交的 URL 地址,通过 method 属性指定提交的方式为 POST,并通过 enctype 属性指定数据的编码方式为 application/x-www-form-urlencoded

1651019925131

注意:由于 enctype 的默认值就是 application/x-www-form-urlencoded,因此上述的 enctype 可以被省略

在旧版本 表单提交的问题

表单身兼数职:既负责采集数据,又负责把数据提交到服务器!表单的默认提交行为会导致页面的跳转

解决方案:

表单只负责采集数据;

Ajax 负责将数据提交到服务器。(符合:职能单一的原则)

2-引入JQ.JS-快速获取表单数据-序列化

序列化 (对象与字符串转化)

把对象或者数组 转成 字符串格式 过程 序列化 JSON.stringify();

把字符串格式 转成 对象或者数组 反序列化 JSON.parse()

可以快速获取 form表单中的 input标签 带有 name 属性的数据

注意: input 标签中 没有name属性的 就会获取不到

引入 JQ .JS文件 直接用jq的 serialize()

  <body>
    <form>
      <input type="text" name="username" />
      <input type="text" name="password" />
      <input type="text" />
      <button type="button">获取表单数据</button>
    </form>
    <script src="./lib/jquery.js"></script>
    <script>
      // 序列化
      // 把对象或者数组 转成 字符串格式  过程  序列化  JSON.stringify();
      // 把字符串格式 转成 对象或者数组    反序列化   JSON.parse()
      const button = document.querySelector('button');

      // 假设我想要使用 快速获取表单数据 序列化 功能
      // 1 直接用jq的 serialize
      // 2 es6 新的对象 用这些新的对象 构造自己的序列化 方法 - 没有演示
      // 3 传统- 自己写代码 获取每一个input标签的 自己写代码进行字符串拼接  没有演示

      button.addEventListener('click', function () {
        // 使用jq的方法 获取表单的数据 (字符串)

        // username=11&password=22  get请求 两种传递参数的方式
        // 1 params对象
        // 2 在url上拼接字符串的形式 http:/api?username=11&password=22
 
        const data = $('form').serialize();; 
        console.log(data);
      });  
    </script>
  </body>

3-利用JS内置对象快速获取表单数据-FormData-URLSearchParaams

FormData作用:

可以快速获取 form 标签中有name属性的 表单数据

FormData js内置的对象 处理表单数据 需要被new 出来使用

公式:

const form = new FormData (document.querySelector('form'));

把 form表单-里面所有的表单标签中带有 name 属性 转成 formdta对象

form 对象也可以使用 forEach 方法 会遍历 它当中包含着 表单的数据

form.forEach((值,键)=>{});

        form.forEach((value, key) => {
          // value =  username表单的值
          // key = username
          usp.append(key, value);
        });

URLSearchParaams作用:

可以把 普通对象 formdata对象 快速转化成字符串格式

URL Search Params 用来处理 url 上的参数 对象 也是可以被new

公式:

const usp = new URLSearchParams();

usp 有一个方法 toString() 把添加到它身上的 数据 转成 url 的参数的格式

代码示例:

    <form>
      <input type="text" name="username" />
      <input type="text" name="password" />
      <input type="text" name="gender" />
      <button type="button">提交数据</button>
    </form>
    <script>
      const button = document.querySelector("button");
         // 1 快速 把 form表单中的带有name属性的数据 设置到 formdata 中
        const form = new FormData(document.querySelector("form"));
        // 2 创建把数据 转成 get 参数格式 对象
        const usp = new URLSearchParams();
        // 3 对form遍历
        form.forEach((value, key) => {
          // value =  username表单的值
          // key = username
          usp.append(key, value);
        });
        // 4 usp 获取到了所有它等待转化的数据  开始进行转化
        const data = usp.toString();
        console.log(data);//username=11&password=22&gender=33
       });
          

两个内置对象一起使用技巧

两个内置对象放在一起可以省略 forEach遍历

    <form>
      <input type="text" name="username" value="123" />
      <input type="text" name="password" value="456" />
    </form>
    <script>
      // const data = {
      //   bookname: '111',
      //   author: '222',
      //   publisher: '33',
      //   appkey: '444',
      // };

      // // 利用usp URLSearchParams 快速转成 字符串
      // const usp = new URLSearchParams(data); // formdata 对象
      // console.log(usp.toString());

      const form = new FormData(document.querySelector("form"));
      const usp = new URLSearchParams(form);  //两个内置对象放在一起可以省略 forEach遍历 
      console.log(usp.toString()); //username=123&password=456
    </script>

4-axios-get简写

​ axios.get() 直接发送get请求 可以支持 url地址 , 字符串

axios.get(Url)

axios.get(Url,{params:{参数}}) ;

方式1

        axios
          .get("http://www.itcbc.com:3006/api/getbooks?appkey=pengy123")
          .then((reslut) => {
            console.log(reslut);
          });

方式2

        axios
          .get("http://www.itcbc.com:3006/api/getbooks", {
            params: {
              author: "我自己",
              appkey: "pengy123",
            },
          })
          .then((reslut) => {
            console.log(reslut);
          });

5-axios-post简写

post请求

axios.post(url,参数(对象));

axios.post(url,参数(字符串格式));

方式1

      const str = "bookname=9999&author=888&publisher=7777&appkey=pengy123";
      axios
        .post("http://www.itcbc.com:3006/api/addbook", str)
        .then((result) => {
          console.log(result);
        });

方式2

        axios
          .post("http://www.itcbc.com:3006/api/addbook", {
            bookname: "1111",
            author: "2222",
            publisher: "3333",
            appkey: "pengy123",
          })
          .then((reslut) => {
            console.log(reslut);
          });

6-axios-delete简写

axios.post(url,参数(对象));

不支持字符串简写

      axios
        .delete("http://www.itcbc.com:3006/api/delbook", {
          params: {
            id: 16601,
            appkey: "pengy123",
          },
        })
        .then((reslut) => {
          console.log(reslut);
        });

7-文件上传-图片到服务器

1 显示到网页

可以去 MDN文档网址中查询

1 通过 input 标签 中的 type = 'file' 属性来选择文件

2 accept 属性 就可以 限定用户选择类型

accept = "image/*"      只能选择 图片

​ accept = "image/,video/ 只能选择 图片 或者视频

3 给 input 标签 绑定 change 事件 图片上传浏览器内存中 就触发

4 通过 this.files 来获取文件数组

5 - URL.createObjectURL 新的 JS内置对象 把浏览器内存中图片文件的地址 获取出来

代码示例:

     <img src="" alt="" />
    <input type="file" accept="/image/*" />
  <script>
	 const input = document.querySelector("input");
      const img = document.querySelector("img");

      input.addEventListener("change", function () {
        // console.log('浏览器拿到图片文件了');
        // console.log(this.files);
        const file = this.files[0]; // 要上传的文件对象

        //新的 JS内置对象 把浏览器内存中图片文件的地址 获取出来
        const src = URL.createObjectURL(file);
        console.log(src);
        img.src = src;
      });</script>

2 把图片上传到指定服务器

​ 根据接口文档的要求来代码

​ url、请求类型、请求参数(重点)

​ url www.itcbc.com:3006/api/formdat…

​ method :'post '

​ 请求参数 上传文件 给后端的参数 肯定是 formdata 类型

​ const formdata = new FormData() ;// 创建一个空formdata对象

​ 参数名称 avatar 参数值 file

​ formdata.append("avatar", file); // 接口要求 把文件追加到 formdata对象

1651025094873

    <img src="" alt="" />
    <input type="file" accept="image/*" />
    <script src="./lib/axios.js"></script>
    <script>
      const input = document.querySelector("input");
      const img = document.querySelector("img");
      input.addEventListener("change", function () {
        const file = this.files[0];
        const src = URL.createObjectURL(file);
        img.src = src;

         // 参数名称 avatar  参数值 file
        const formdata = new FormData();// 创建一个空formdata对象
        formdata.append("avatar", file);// 接口要求 把文件追加到 formdata对象

        //简写
        // axios
        //   .post("http://www.itcbc.com:3006/api/formdata", formdata)
        //   .then((result) => {
        //     console.log(result);
        //   });

        // 把数据上传到服务器中 即可
        axios({
          method: "post",
          url: "http://www.itcbc.com:3006/api/formdata",
          data: formdata,
        }).then((result) => {
          console.log(result);
        });
      });
    </script>

8- 拦截器

什么是拦截器?

拦截器(interceptors)用来全局拦截 axios 的每一次请求与响应。

好处:可以把每个请求中,某些重复性的业务代码封装到拦截器中,提高代码的复用性。

可以去 axios 中文网 找到对应的代码

1651025817161

1 很多功能 都需要和服务器 交互 发送网络请求

上传头像 网络很慢、上传的文件很大

整个页面 没有相应的 状态

发送请求的时候 都显示一个 加载中的友好提示

2 自己根据发送的请求来 显示加载中! axios内置的拦截器代码功能 在任意的请求

​ 在发送请求前 拦截 处理一下 - 显示加载中

​ 在数据响应来 拦截 处理一下 - 关闭加载中

9-FormData 介绍-PPT介绍

FormData 是一个浏览器对象。用于管理表单数据。

可以这样理解,FormData 的作用和 jQuery中的 serialize() 作用一样,用于快速收集表单数据

并且可以将创建的FormData对象直接提交给接口。

典型应用场景:FormData + Ajax 技术实现文件上传的功能。

FormData和serialize的区别

共同点:

  1. 都需要设置表单各项的name属性。
  2. 都能快速收集表单数据
  3. 都能够获取到隐藏域()的值
  4. 都不能获取禁用状态(disabled)的值

不同点:

  1. FormData属于原生的代码;serialiaze是jQuery封装的方法
  2. FormData可以收集文件域()的值,而serialize不能。如果有文件上传,则必须使用FormData。
  3. 得到的结果的数据类型不一样(知道即可)

FormData基本使用方法

1651026267477

FormData的API方法

在提交数据前,可以使用下列API方法对数据进行查看和修改

1651026227035


04-报文-http状态码-原生ajax.XML代码-ajax封装-防抖-节流

1-请求报文-响应报文

作用: 方便前端测试代码出错

1 请求报文规定了客户端以什么格式把数据发送给服务器

2 响应报文规定了服务器以什么格式把数据响应给客户端

1. 请求报文-格式

请求报文由请求行(request line)、请求头部( header )、空行 和 请求体 4 个部分组成

1651147078779

注意:

在浏览器中,GET 请求比较特殊,它只有请求头,没有请求体。 在浏览器中,POST、PUT、PATCH、DELETE 请求既有请求头,又有请求体

2请求体-对应的请求头

除GET请求以外,其他4种常用的请求方式,都可以设置请求体。 请求体的大小没有限制,所以可以提交大量的数据

常用的请求体格式有如下三种:
参数=值&参数=值查询字符串格式
{"id"=1,"name"="张三"}JSON格式
new FormData()FormData对象格式

请求体请求的时候,设置了不同格式的请求体,需要一个对应的请求头

对应的请求头利用编辑器的代码提示 form标签 enctype 获取 content-type 属性
参数=值&参数=值Content-Type: application/x-www-form-urlencoded
{"id"=1,"name"="张三"}Content-Type: application/json
new FormData()不用设置 Content-Type

3.响应报文-格式

响应报文由状态行、响应头部、空行 和 响应体 4 个部分组成

1651147169640

思维导图:

1651148044501

1651148060356

2-http 状态码 - 业务码

1 http 响应状态码

概念:

http 响应状态码(Status Code)由三位数字组成,用来标识响应成功与否的状态。

作用:

客户端浏览器根据响应状态码,即可判断出这次 http 请求是成功还是失败了。

主要记住5个大区别:

1651148163634

常见的 http 响应状态码

1651148207073

2 业务码

通常是公司的后端人员自己设置的错误码 每个公司的业务码都不同 例如:

1651148544630

两者的区别:

1.http状态码 是行业通用 业务状态码 只是你的公司通用

2.http状态 在 响应报文-状态行看见 业务状态码 响应体看见

3.http状态码表示结果 你的请求有没有正确的给到服务端 业务状态码 你当前请求的业务是否正常响应

1651148635806

3-原生ajax代码- XMLHttpRequest

什么是 XMLHttpRequest

是浏览器内置的一个构造函数

作用:

基于 new 出来的 XMLHttpRequest 实例对象,可以发起 Ajax 的请求。 axios 中的 axios.get()、axios.post()、axios() 方法,都是基于 XMLHttpRequest(简称:XHR) 封装出来的!

使用 XMLHttpRequest 发起 GET 请求

主要4个实现步骤:

1 const xhr = new XMLHttpRequest(); JS内置对象

2 xhr.open() 请求类型 url

3 xhr.send(); 发送出去

4 xhr.addEventListener("load", function () { this.response }); 监听事件 数据响应返回

      //1 创建 xhr 对象  XMLHttpRequest 是JS内置对象
      const xhr = new XMLHttpRequest();
      //2 调用 open 方法 指定类型 get 或post   url
      xhr.open("get", "http://www.itcbc.com:3006/api/getbooks");
      //3 发送出去  send
      xhr.send();
      //4 监听 load  数据响应事件
      xhr.addEventListener("load", function () {
        console.log("数据回来了");
        //this  指向自己
        console.log(this.response);
        //字符串转对象格式
        let obj = JSON.parse(this.response);
        console.log(obj);
      });

3-1原生-get请求参数

只能写在 xhr . open ( 'get' , url + 参数 )

      const xhr = new XMLHttpRequest();
      //  get 携带 参数 要写在url 后面 是字符串格式
      xhr.open("get", "http://www.itcbc.com:3006/api/getbooks?appkey=pengy123");
      xhr.send();
      xhr.addEventListener("load", function () {
        const obj = JSON.parse(this.response);
        console.log(obj);
      });

3-2原生-post-携带参数-字符串

注意: post请求的参数 只能写在 send()括号里

post 三种不同数据格式的参数

1 a=b&c=d 同时也需要指定 content-type 才行!!

2 对象格式 {a:"b",c:"d"} 同时也需要指定 content-type 才行!!

3 formdata 数据 不用指定 浏览器会自动设置

技术:

利用JS内置对象,将 对象转成 字符串格式 如: a=1&b=2

      // 把data 转成 a=b&c=d ....  URLSearchParams
      const usp = new URLSearchParams(data);
      const str = usp.toString();
      console.log(str);

用原生ajax-post请求必须要设置对应的请求头

可以利用编辑器的代码提示 form标签 enctype 获取 content-type 属性

字符串对应请求头: "application/x-www-form-urlencoded

xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

代码示例:

    <!-- <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");
      // post请求的参数 只能写在 send()
      // post 三种不同数据格式的参数
      // 1 a=b&c=d   同时也需要指定 content-type 才行!!
      // 2 对象格式  {a:"b",c:"d"} 同时也需要指定 content-type 才行!!
      // 3 formdata 数据
      let data = {
        bookname: "9从入门到精通9",
        author: "我自己",
        publisher: "黑马出版社",
        appkey: "pengy123",
      };
      // 把data 转成 a=b&c=d ....  URLSearchParams
      const usp = new URLSearchParams(data);
      const str = usp.toString();
      console.log(str);
      // 设置对应的 content-type
      xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      xhr.send(str); // 传递 a=b&c=d
      xhr.addEventListener("load", function () {
        console.log(this.response);
      });

3-3原生-post-携带参数-JSON

注意: post请求的参数 只能写在 send()括号里

技术:

将对象 转成 JSON.stringify() 格式

      // 设置对应的 content-type
      xhr.setRequestHeader("Content-type","application/json");
      const str =JSON.stringify(data);
      xhr.send(str); // 传递 a=b&c=d  

代码示例:

    <!-- 利用编辑器的代码提示  enctype  获取 content-type 属性 -->
    <!-- <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);
      });

3-4 原生-post-携带参数-FormData

FormData 事用于 文件上传使用

技术:

change事件 输入框的值发生改变-输入框失去焦点 才触发

用 input 标签 file 属性 input标签绑定 change 事件

代码示例:

  <body>
    <input type="file" accept="image/*" />
    <script>
      const input = document.querySelector('input');
      input.addEventListener('change', function () {
        
        const file = this.files[0];
        //formdata 是用于文件上传
        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>

4-ajax封装

定义一个ajax函数

ajax函数是自定义的 Ajax 函数,它接收一个配置对象作为参数。配置对象中包含如下 5 个参数选项:

参数选项说明
type请求的类型(GET 或 POST)
url请求的 URL 地址
paramsURL 末尾拼接的查询参数
data请求体数据,有三种格式,分别是(FormData 格式、JSON 格式、普通字符串格式)
success请求成功之后的回调函数

主要:

1 ajax 是一个函数

2 它接受一个 参数 对象格式

3 需要在ajax函数中 写完 整个原生ajax 发送请求的代码

代码示例:

      /* 
      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);
        },
      };
      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);
          console.log(obj);
        });
      }

4-1 ajax封装-get请求

技术核心: 默认值加对象解构

封装的时候考虑到用户 (可能带参数,可能不带参数) 利用对象解构 和参数默认值

代码示例:

      const option = {
        url: "http://www.itcbc.com:3006/api/getbooks",
        type: "get",
        data: "appkey=wanshao1234",
        success(result) {
          // result 等于 要等于响应的数据 =  对象格式
          console.log(result);
        },
      };

      ajax(option);
      //封装的时候考虑到用户 (可能带参数,可能不带参数)  利用对象解构 和参数默认值
      function ajax({ type, url, 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 () {
          //返回数据  this.response
          //考虑到数据更好看,将字符串转 数组对象
          const obj = JSON.parse(this.response);
          success(obj);
        });
      }

4-2ajax封装-get对象格式(完整)

技术核心:判断是否对象

​ URLSearchParams().toString() 将对象格式转字符串格式 a=1&b=2

data = new URLSearchParams(data).toString()

代码示例:

     //1  获取 密钥"appkey=wanshao1234" 的数据
	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",
          bookname: "今晚吃啥",
        },
        success(result) {
          console.log(result);
        },
      });

      //封装的时候考虑到用户 (可能带参数,可能不带参数)  利用对象解构 和参数默认值
      function ajax({ type, url, data = "", success }) {
        const xhr = new XMLHttpRequest();

        if (typeof data === "object") {
          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 () {
          //返回数据  this.response
          //考虑到数据更好看,将字符串转 数组对象
          const obj = JSON.parse(this.response);
          success(obj);
        });
      }

5-ajax封装-post-data传参(完整)

判断当前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);

技术:

实例 instanceof 构造函数

      // FormData 构造函数 (爸爸)
      // data 实例 (儿子)
      const data = new FormData();
      //  判断当前数据 字符串类型 typeof
      console.log( typeof data === "object" ); // 对象类型  true
      // 判断你儿子 是不是亲生
      //  儿子   instanceof  爸爸
      //  实例   instanceof  构造函数
      console.log( data instanceof FormData );//true

步骤:

判断请求类型 是 get 还是 post

1 get类型

判断是否是对象格式, 是对象格式 就转成字符串格式 不是就默认值等于空

1651155278692

2 post类型

2-1 判断是不是字符串格式 是就给他添加 指定请求头

1651155468584

2-2 判断是不是 FormData 实例 还是普通对象

1651155571463

2-3 普通对象 添加指定请求头 以及对象格式转换 JSON.stringify()

1651155716508

代码示例:

  <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 data = new FormData();

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

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


      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];
        // 获取FormData 实例
        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>

6-防抖

作用: 防抖 防止抖动

用在输入框中 实现 不用用户按下回车键 就发送请求

技术原理:

在input 事件中 利用延时器 在上一个延时器未结束时 ,就清除,清除的同时在开始一个新的延时器,直到用户输入完内容

1 用新的一次输入来清除上一次的延时器

2 同时开启一个新的延时器

主要: 用于让用户输入内容不用按下回车键就会发送请求

代码示例:

<!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 () {
          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>

7-节流 (节省服务器性能)

使用场景:

节流

上一次的业务没有结束的话 不允许开启下一次业务

使用场景 移动端分页 - 倒计时按钮 等等

原理:

这一次请求还没有结束 就不能开启下一个请求

技术:

1 可以使用 按钮 禁用 以及 启用

2 声明 一个变量等于 false 开关

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

点击按钮的时候先判断 isLoadding true还是false

​ true 请求在发送中 return

​ false 没有请求

​ 先设置 isLoadding true

​ 发送请求出去

​ 请求回来了 设置 isLoadding = false

代码示例:

<!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>