Ajax(三)

112 阅读3分钟

Ajax第三天

一、案例-新闻接口

  1. 需求

(1)根据接口文档的要求 获取数据 分析数据结构

(2)渲染成标签 显示在网页当中

2.获取接口地址

url: "http://www.itcbc.com:3006/api/news"

3.请求类型

method: "get"

4.标签结构搭建

const html = arr.map((value) => `
<li>
  <h3>${value.title}</h3>
  <img src="http://www.itcbc.com:3006${value.img}" alt="" />
  <h6>${value.source}</h6>
  <p>${value.time}</p>
</li>
 `).join("");

5.完整代码

<!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>01-新闻-作业.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      ul {
        width: 1200px;
        margin: 100px auto;
        list-style: none;
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
      }
      li {
        width: 380px;
        border: 1px solid #ccc;
      }
    </style>
  </head>
  <body>
    <ul></ul>
    <script src="./lib/axios.js"></script>
    <script>
      /* 
      需求
      1 根据接口文档的要求 获取数据 分析数据结构 
      2 渲染成标签 显示在网页当中
       */

      axios({
        url: "http://www.itcbc.com:3006/api/news",
        method: "get",
      }).then((result) => {
        //  console.log(result);
        const arr = result.data.data;
        console.table(arr);
        const html = arr
          .map(
            (value) => `
        <li>
        <h3>${value.title}</h3>
        <img src="http://www.itcbc.com:3006${value.img}" alt="" />
        <h6>${value.source}</h6>
        <p>${value.time}</p>
      </li>
        `
          )
          .join("");
        document.querySelector("ul").innerHTML = html;
      });
    </script>
  </body>
</html>

二、put请求类型:编辑

1.主体结构
<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>

// 通过form表单获取点击编辑的数据,并同步到form个input标签中,编辑内容点击编辑实现服务器数据编辑更改
<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="btnedit" />
      </form>
</div>
2.通过函数,get请求类型获取服务器原有数据
// 获取运行函数,渲染页面
getData();

// 定义一个方法 发送请求 获取数据  渲染页面
 function getData() {
   axios({
     url: "http://www.itcbc.com:3006/api/getbooks",
     method: "get",
     params: {
       appkey: "wanshao1234",
     },
   }).then((result) => {
     console.log(result);
     arr = result.data.data;
     const 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 class="editbtn" data-index="${index}" href="javascript:;" >编辑</a></td>
         </tr>
          `;
       }).join("");
     tbody.innerHTML = html;
   });
 }
3.注册事件
const tbody = document.querySelector("tbody");
// 全局变量
let arr; // 列表数据
let id; // 被点击的数据的id
const booknameValue = document.querySelector(".bookname");
const authorValue = document.querySelector(".author");
const publisherValue = document.querySelector(".publisher");
const btnedit = document.querySelector(".btnedit");
4.绑定点击“编辑”事件,获取对应编辑对象的id
tbody.addEventListener("click", function (event) {
        if (event.target.className === "editbtn") {
          // 获取a身上的下标
          const { index } = event.target.dataset;
          //  获取到 另外一个方法中的 数组
          console.log(arr[index]);
          // 把对应的数据显示到表单中
          booknameValue.value = arr[index].bookname;
          authorValue.value = arr[index].author;
          publisherValue.value = arr[index].publisher;
          // 获取到被编辑的数据id
          id = arr[index].id;
        }
      });
5.点击编辑,将编辑信息数据修改,并同步到服务器,再次渲染更新后的数据
btnedit.addEventListener("click", function () {
        // 获取表单的值
        const data = {
          // 如何去获取
          id: id,
          bookname: booknameValue.value,
          author: authorValue.value,
          publisher: publisherValue.value,
          appkey: "wanshao1234",
        };
        // 发送一个编辑 请求
        axios({
          url: "http://www.itcbc.com:3006/api/updatebook",
          method: "put",
          // query - params
          // body  - data
          data,
        }).then((result) => {
          console.log(result);
          getData();
        });
        // 提示编辑成功 ->调用 getData 实现重新获取最新的数据
      });

三、form表单获取全部数据

1.form> 标签最重要的 3 个属性分别是 action、method 和 enctype。

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

1651046744280.png

2.旧方式 提交数据 form标签的方式 提交

(1)肯定会出现 刷新页面 调整页面的情况 (体验! 很糟糕)

(2)输入框没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="password" name="password" />
      </div>
      <div>
        <label for="">测试</label>
        <input type="text" />
      </div>
      <button>提交</button>
    </form>
3.新的方式 ajax

(1)异步 网络请求 (异步 同时执行多个事情 - 你一边正在使用网页功能而且数据提交 同时进行(整个网页 ))

(2)规范 只要写到input标签想要数据提交 习惯的加上 name属性

(3)如果使用ajax的技术来提交数据 是完全不给标签添加name属性

(4)习惯下来 form input标签name 都一直在使用

4.序列化

(1)序列化

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

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

(2)假设我想要使用 快速获取表单数据 序列化 功能

①直接用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>

      const button = document.querySelector("button");
      button.addEventListener("click", function () {
        const data = myfunc("form"); // 不要这么做 人品坏
        console.log(data);
      });

      // function $() {
      //   console.log(1);
      // }
      // $();

      function myfunc(query) {
        return $(query).serialize();
      }
    </script>
  </body>

②es6 新的对象 用这些新的对象 构造自己的序列化 方法 - 没有演示

<body>
    <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");

      button.addEventListener("click", function () {
        const data123 = getForm("form");
        console.log(data123);
        return data123;
      });
      //  FormData  js内置的对象  处理表单数据  需要被new 出来使用
      function getForm(query) {
          
        // 把 form表单-里面所有的表单标签-name属性 转成 formdta对象
        // const formObj = new FormData(document.querySelector('form'));
        // formObj  对象 包含所有的表单数据(input name)
        const form = new FormData(document.querySelector(query));
        const usp = new URLSearchParams();
        form.forEach((value, key) => {
          usp.append(key, value);
        });
        const data = usp.toString();
        return data;
      }
        
      
      /* 
      FormData  快速获取表单的数据
      1 forEach
      URLSearchParams 数据转成 get传参数据格式 
      1 append
      2 toString()
       */
    </script>
  </body>

③传统- 自己写代码 获取每一个input标签的 自己写代码进行字符串拼接 没有演示

④讲解js基础 对象 数组 字符串 转来转去

5.axios执行post请求传参格式

(1)对象类型:data: {bookname: '从入门到精通',author: '我自己',publisher: '黑马出版社',appkey: 'wanshao1234', },

(2)字符串格式类型 :如bookname=从入门到精通&author=我自己&publisher=黑马出版社&appkey=wanshao1234

    <script>
      /* 
      axios 执行post请求 传递参数 data 传参
      data 可以接受的参数的类型 
      1 对象类型 
      2 字符串格式类型  
        bookname=从入门到精通&author=我自己&publisher=黑马出版社&appkey=wanshao1234
      
       */
      const button = document.querySelector("button");
      button.addEventListener("click", function () {
        axios({
          method: "post",
          url: "http://www.itcbc.com:3006/api/addbook",
          data: "bookname=从入门到精通&author=我自己&publisher=黑马出版社&appkey=wanshao1234",
          // data: {
          //   bookname: '从入门到精通',
          //   author: '我自己',
          //   publisher: '黑马出版社',
          //   appkey: 'wanshao1234',
          // },
        }).then((result) => {
          console.log(result);
        });
      });
    </script>
6.普通对象转URLSearchParams
  <body>
    <form>
      <input type="text" name="username" value="123" />
      <input type="text" name="password" value="456" />
    </form>
    <script src="./lib/axios.js"></script>
    <script>
      const data = {
        bookname: "111222",
        author: "222222",
        publisher: "33333",
        appkey: "wanshao1234",
      };

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

      // const form = new FormData(document.querySelector('form'));
      // const usp = new URLSearchParams(form);
      // console.log(usp.toString());//  可以的!!!
    </script>
  </body>
7.axios简写的代码

(1)axios.get() 直接发送get请求

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

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

(2)axios.post() 直接发送post请求

// axios.post(url,参数(对象));
axios.post("http://www.itcbc.com:3006/api/addbook", {
          bookname: "post请求1",
          author: "post请求222",
          publisher: "post请求33",
          appkey: "wanshao1234",}).then((result) => {
             console.log(result);
             });

// axios.post(url,参数(字符串格式));
const url = "http://www.itcbc.com:3006/api/addbook";
const query ="bookname=111222&author=222222&publisher=33333&appkey=wanshao1234";
      axios.post(url, query).then((result) => {
        console.log(result);
      });

(3)axios.delete() 直接发送delete请求

(4)axios.put() 直接发送put请求

8.拦截器

(1)拦截器(interceptors)用来全局拦截 axios 的每一次请求与响应。 好处:可以把每个请求中,某些重复性的业务代码封装到拦截器中,提高代码的复用性(提高用户体验)。

      // 添加请求拦截器
      axios.interceptors.request.use(
        function (config) {
          // 在发送请求之前做些什么
          // console.log('发送前 拦截器 ');
          document.querySelector("img").style.display = "block";
          return config;
        },
        function (error) {
          // 对请求错误做些什么
          return Promise.reject(error);
        }
      );

(2)原理

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

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

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

(3)案例-加载中(控制加载过程中间隙,图片显示与不显示,增加用户体验)

<!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-拦截器.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      img {
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        display: none;
      }
    </style>
  </head>
  <body>
    <img src="./images/gotop.gif" alt="" width="50px" />
    <script src="./lib/axios.js"></script>
    <button>发送请求</button>
    <script>

      axios.interceptors.request.use(
        function (config) {
          // 在发送请求之前做些什么
          document.querySelector("img").style.display = "block";
          return config;
        },
        function (error) {
          // 对请求错误做些什么
          return Promise.reject(error);
        }
      );

      // 添加响应拦截器
      axios.interceptors.response.use(
        function (response) {
          document.querySelector("img").style.display = "none";
          return response;
        },
        function (error) {
          // 对响应错误做点什么
          return Promise.reject(error);
        }
      );

      const button = document.querySelector("button");
      button.addEventListener("click", function () {
        // 发送网络请求
        axios
          .get("http://www.itcbc.com:3006/api/getbooks?appkey=wanshao1234")
          .then((result) => {
            console.log(result);
          });
      });
    </script>
  </body>
</html>

四、上传图片

1.需求

(1)先允许用户选择本地的图片(很快 图片 上传视频)

(2)指定文件上传的类型 只能是图片不能是其他 input标签一个属性 指定上传的文件的类型 accept

​ accept = "image/*"

​ accept = "image/,video/,.jpg"

developer.mozilla.org/zh-CN/docs/…

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

(4) this.files来获取文件数组

(5)可选

①直接把文件开始上传

②先在网页显示一下用户选择的图片 - 来确定是不是一张

(6)把图片上传到指定服务器:图片文件?axios

2.案例

 <body>
    <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);
        const src = URL.createObjectURL(file);
        // 让图片显示出来
        console.log(src);
        img.src = src;
      });
    </script>
  </body>

3.案例

<body>
    <img src="" alt="" />
    <input type="file" accept=".gif" />
    <script src="./lib/axios.js"></script>
    <script>
      /* 
      2 把图片上传到指定服务器 
        2 根据接口文档的要求来代码 
          url、请求类型、请求参数(重点)  

          url http://www.itcbc.com:3006/api/formdata
          method post 
          请求参数 上传文件 给后端的参数 肯定是 formdata 类型 
      
       */
      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({
          method: "post",
          url: "http://www.itcbc.com:3006/api/formdata",
          data: formdata,
        }).then((result) => {
          console.log(result);
        });

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