Ajax的了解

78 阅读6分钟

服务器

  • 服务器的本质:就是一台电脑
  • 作用:存放任何网页需要的资源(数据也是资源)

客户端

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

URL地址

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

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

请求-响应(两个步骤)

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

Ajax

  • Ajax是浏览器中的技术:用来实现客户端网页请求服务器的数据。
  • 一种使用JS来异步获取XML格式数据的技术
  • 同步:代码执行马上有结果
  • 异步:代码执行不一定马上有结果

请求

请求方式

Ajax请求数据有5种常见方式

  1. POST——向服务器新增数据
  2. GET——从服务器获取数据
  3. DELETE——删除服务器上的数据
  4. PUT——更新服务器上的数据(侧重于完整更新:更新用户的完整信息)
  5. PATCH——更新服务器上的数据(侧重于部分更新:更新用户的手机号码)

请求参数

查询数据-params:{}

一条参数

axios({
            method:"get",
            url:"http://www.itcbc.com:3006/api/getbooks",
            params:{
                bookname:"万少"
            }
        }).then(result=>{
            const arr=result.data.data
            render(arr)
        })

多条参数

axios({
            method:"get",
            url:"http://www.itcbc.com:3006/api/getbooks",
            params:{
                bookname:"万少",
                id:"5946"
            }
        }).then(result=>{
            const arr=result.data.data
            render(arr)
        })
url拼接参数

一条参数

axios({
        method: "get",
        // 拼接参数时不需要单双引号
        url: "http://www.itcbc.com:3006/api/getbooks?id=5927",
      }).then((result) => {
        const arr = result.data.data;
        render(arr);
      });

多条参数

axios({
        method: "get",
        // 拼接参数时不需要单双引号
        url: "http://www.itcbc.com:3006/api/getbooks?id=5927&bookname=窗边的小豆豆",
      }).then((result) => {
        const arr = result.data.data;
        render(arr);
      });
根据用户输入查询数据案例

用到的技术

  • 参数默认值
  • 变量拼接字符串
  • 数据驱动视图
<!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>
    <input type="text" id="user-enter" />
    <table>
      <thead>
        <tr>
          <th>ID</th>
          <th>书名</th>
          <th>作者</th>
          <th>出版社</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>
    <script src="../Ajax-day01/lib/axios.js"></script>
    <script>
      const tbody = document.querySelector("tbody");
      const userEnter = document.querySelector("#user-enter");
      getData();
      userEnter.addEventListener("keyup", function (e) {
        if (e.key === "Enter") {
          const value = this.value.trim();
          if (value) {
            const query=`?bookname=${value}`
            getData(query);
            this.value = "";
          } else {
            getData();
          }
        }
      });

      // 获取数据单独封装一段代码
      // js高级-参数默认值
      function getData(query = "") {
        axios({
          method: "get",
          url: `http://www.itcbc.com:3006/api/getbooks` + query,
        }).then((result) => {
          const arr = result.data.data;
          render(arr);
        });
      }

      // 渲染函数也单独封装
      function render(arr) {
        const arrHtml = arr
          .map(
            (value) => `
            <tr>
                <td>${value.id}</td>
                <td>${value.bookname}</td>
                <td>${value.author}</td>
                <td>${value.publisher}</td>
            </tr>
            `
          )
          .join("");
        tbody.innerHTML = arrHtml;
      }
    </script>
  </body>
</html>

添加数据

data:{}
  • 提交方式——method:"post"
  • url——后端提供(肯定跟获取数据的url不一样)
  • 传参方法——data:{}
<body>
    <button>新增数据</button>
    <script src="../Ajax-day01/lib/axios.js"></script>
    <script>
      const btn = document.querySelector("button");
      btn.addEventListener("click", function () {
        axios({
          method: "post",
          url: "http://www.itcbc.com:3006/api/addbook",
          data: {
            bookname: "守护甜心",
            author: "越前龙马",
            publisher: "蜡笔小新",
          },
        }).then((result) => {
          console.log(result);
        });
      });
      // 新增数据 url 请求方式method 参数对象都有所不同
    </script>
  </body>
用户输入新增数据
<!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>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      body {
        display: flex;
        flex: 1;
      }
      table {
        display: block;
        width: 50%;
      }
      table tbody tr:nth-child(odd){
        background-color: yellow;
      }
      table,
      .user-box {
        margin: 50px;
        float: left;
      }
      input {
        display: block;
        margin: 10px auto;
      }
    </style>
  </head>
  <body>
    <div class="user-box">
      <input type="text" id="bookname" placeholder="书名" />
      <input type="text" id="author" placeholder="作者" />
      <input type="text" id="publisher" placeholder="出版社" />
      <button>添加数据</button>
    </div>
    <table>
      <thead>
        <tr>
          <th>ID</th>
          <th>书名</th>
          <th>作者</th>
          <th>出版社</th>
        </tr>
      </thead>
      <tbody>
        
      </tbody>
    </table>

    <script src="../Ajax-day01/lib/axios.js"></script>
    <script>
      const tb=document.querySelector("tbody")
      const booknameDom=document.querySelector("#bookname")
      const authorDom=document.querySelector("#author")
      const publisherDom=document.querySelector("#publisher")
      const btn=document.querySelector("button")
      // 刷新页面渲染表单
      getData()
      // 按钮事件注册
      btn.addEventListener("click",function () {
        const bookname=booknameDom.value
        const author=authorDom.value
        const publisher=publisherDom.value
        // ES6方式设置属性
        const data={
          bookname,
          author,
          publisher
        }
        // 调用新增
        addData(data)
      })

      // 新增数据函数
      function addData(data) {
        axios({
          method:"post",
          url:"http://www.itcbc.com:3006/api/addbook",
          // es6
          data
        }).then(result=>{
          console.log(result);
          getData()
        })
      }

      // 先封装查询函数
      function getData() {
        axios({
          method:"get",
          url:"http://www.itcbc.com:3006/api/getbooks"
        }).then(result=>{
          if(result){
            console.log("获取result成功");
            const dataArr=result.data.data
            render(dataArr)
          }
        })
      }

      // 渲染函数
      function render(arr) {
        const html=arr.map(value=>`
        <tr>
          <td>${value.id}</td>
          <td>${value.bookname}</td>
          <td>${value.author}</td>
          <td>${value.publisher}</td>
        </tr>
        `).join("")
        tb.innerHTML=html
      }
    </script>
  </body>
</html>

编辑数据

  1. 点击编辑操作,获取数组下标或者数据id(数据有隐藏的详细信息时用id),将数据传到输入框内
  2. 用户编辑文本内容
  3. 点击修改按钮,设置const data={},将表单内容添加进data
  4. 文档说明id必填,但是用户一般没有对id的需求,所以在第一步的时候就直接获取数组下标,后续设置为原值即可
  <body>
    <div class="user-box">
      <input type="text" id="bookname" placeholder="书名" />
      <input type="text" id="author" placeholder="作者" />
      <input type="text" id="publisher" placeholder="出版社" />
      <button>修改数据</button>
    </div>
    <table border="1">
      <thead>
        <tr>
          <th>ID</th>
          <th>书名</th>
          <th>作者</th>
          <th>出版社</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>

    <!-- 引入axios.js -->
    <script src="../Ajax-day01/lib/axios.js"></script>
    <script>
      const tbody = document.querySelector("tbody");
      const booknameDom = document.querySelector("#bookname");
      const authorDom = document.querySelector("#author");
      const publisherDom = document.querySelector("#publisher");
      const btn = document.querySelector("button");
      let arr = [];
      let id;

      // 按钮点击获取表单数据,修改数据
      btn.addEventListener("click", function () {
        const data = {
          id: id,
          bookname: booknameDom.value,
          author: authorDom.value,
          publisher: publisherDom.value,
          appkey: "1904050132",
        };
        put(data);
      });
      // 修改函数
      function put(data) {
        axios({
          method: "put",
          url: "http://www.itcbc.com:3006/api/updatebook",
          data,
        }).then((result) => {
          console.log(result);
          // 修改成功,重新渲染表单
          getData();
        });
      }

      tbody.addEventListener("click", function (e) {
        if (e.target.nodeName === "A") {
          const i = e.target.dataset.index;
          id = arr[i].id;
          console.log(i);
          booknameDom.value = arr[i].bookname;
          authorDom.value = arr[i].author;
          publisherDom.value = arr[i].publisher;
        }
      });
    </script>
  </body>

删除数据

  • 请求方式——method:"delete"
  • 参数方法——params:{}

confirm()

js内置确认框

  • 点击确定返回true
  • 点击取消返回false
用户删除数据案例
<!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>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      a {
        text-decoration: none;
        color: #000;
        font-size: 14px;
      }
      table {
        display: block;
        text-align: center;
      }
      table td,
      table th {
        padding: 5px 10px;
      }
      table tbody tr:nth-child(odd) {
        background-color: yellow;
      }
      table,
      .user-box {
        margin: 50px;
        float: left;
      }
      input {
        display: block;
        margin: 10px auto;
      }
    </style>
  </head>
  <body>
    <div class="user-box">
      <input type="text" id="bookname" placeholder="书名" />
      <input type="text" id="author" placeholder="作者" />
      <input type="text" id="publisher" placeholder="出版社" />
      <button>添加数据</button>
    </div>
    <table>
      <thead>
        <tr>
          <th>ID</th>
          <th>书名</th>
          <th>作者</th>
          <th>出版社</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>

    <script src="../Ajax-day01/lib/axios.js"></script>
    <script>
      const tb = document.querySelector("tbody");
      const booknameDom = document.querySelector("#bookname");
      const authorDom = document.querySelector("#author");
      const publisherDom = document.querySelector("#publisher");
      const btn = document.querySelector("button");
      const del = document.querySelector("a");
      // 刷新页面渲染表单
      getData();
      // 按钮事件注册
      btn.addEventListener("click", function () {
        const bookname = booknameDom.value;
        const author = authorDom.value;
        const publisher = publisherDom.value;
        // ES6方式设置属性
        const data = {
          bookname,
          author,
          publisher,
        };
        // 调用新增
        addData(data);
      });

      // 新增数据函数
      function addData(data) {
        axios({
          method: "post",
          url: "http://www.itcbc.com:3006/api/addbook",
          // es6
          data,
        }).then((result) => {
          console.log(result);
          getData();
        });
      }

      // 先封装查询函数
      function getData() {
        axios({
          method: "get",
          url: "http://www.itcbc.com:3006/api/getbooks",
        }).then((result) => {
          if (result) {
            console.log("获取result成功");
            const dataArr = result.data.data;
            render(dataArr);
          }
        });
      }

      // 渲染函数
      function render(arr) {
        const html = arr
          .map(
            (value) => `
        <tr>
          <td>${value.id}</td>
          <td>${value.bookname}</td>
          <td>${value.author}</td>
          <td>${value.publisher}</td>
          <td><a data-index="${value.id}" href="javascript:;">删除</a></td>
        </tr>
        `
          )
          .join("");
        tb.innerHTML = html;
      }

      // del按钮
      tb.addEventListener("click", function (e) {
        if (e.target.nodeName === "A") {
          // 简写,params需要的是 id:"xxx"
          const { id } = e.target.dataset.index;
          delData(id);
        }
      });

      // 删除函数
      function delData(id) {
        axios({
          method: "delete",
          url: "http://www.itcbc.com:3006/api/delbook",
          params: {
            // 简写
            id,
          },
        }).then((result) => {
          console.log(result);
          getData();
        });
      }
    </script>
  </body>
</html>

API接口文档

实际开发中出现错误,优先查看文档三个地方

  • 接口url
  • 请求方式
  • 请求参数

network工具

  • 浏览器开发者工具中,有一个面板为network,(新版的chrome浏览器是中文版本的“网络”)

form表单

  • <form>标签最重要的3个属性分别是action,method,enctype
  • 每个表单域必须包含name属性,否则用户填写的信息无法被采集到
  • enctype属性只能搭配post提交方式一起使用;如果是get提交,则enctype没有意义
  • 注意:
    • type="submit"表示提交按钮的意思
    • type属性的默认值就是submit,因此type="submit"可以省略不写

获取表单数据

jQuery的serialize()函数

  <body>
    <form>
      <div class="box1">
        <label>用户名</label>
        <input type="text" name="username" />
      </div>
      <div class="box2">
        <label>密码</label>
        <input type="text" name="password" />
      </div>
      <div class="box3">
        <label>其他</label>
        <input type="text" />
      </div>
      <button>提交</button>
    </form>
    <script src="./lib/jquery.js"></script>
    <script>
        const btn=document.querySelector("button")
        btn.addEventListener("click", function (e){
            // 阻止默认行为
            e.preventDefault()
            const data=$("form").serialize()
            console.log(data);
        })
    </script>
  </body>

原生JS实现获取表单数据(常用)

1、formData()对象,快速获取<form>标签里面有name属性的数据,直接打印看不到对象里面的数据(JS内置对象,处理表单数据,new出来使用)

const form=new FormData(document.querySelector("form"))

2、URLSearchParams()对象,把数据转成参数格式(new使用)

const usp=new URLSearchParams()

3、对formData()对象进行forEach()遍历,追加数据到usp对象中待处理

form.forEach((value,key)=>{
  usp.append(key,value)
})

4、URLSearchParams()对象内置的toString()方法将数据转换成参数形式

const data=usp.toString()
console.log(data);

5、整套代码可以再省略,URLSearchParams()对象可以直接把formData()对象作为参数传进来

const form=new FormData(document.querySelector("form"))
const usp=new URLSearchParams(form)
console.log(usp.toString());

另外:不使用URLSearchParams()对象,用push()join()方法来实现一样的效果

const form=new FormData(document.querySelector("form"))
const data=[];
form.forEach((value,key)=>{
  data.push(`${key}=${value}`)
})
const str=data.join("&")
console.log(str);

快速获取form数据

  • css中,通过input[name]选择器可以选择到有name属性的标签
  • .f1 input[name]——获取类名.f1里面具有name属性的表单标签
  • 利用jsdocument.querySelectorAll+css选择器获取到所有有name属性的标签,通过遍历forEach(dom=>obj[dom.name] = dom.value)将提前设置好的空对象变为属性值一一对应的对象
  • 往后的axios传参直接把obj丢进去即可

文件上传

限制上传文件类型

accept=""属性

具体查看文档

<input type="file" accept="image/*,video/*" />

让用户看到自己选择的图片(修改图片src属性)

  <body>
    <input type="file" accept="image/*,video/*" />
    <img src="" alt="找不到" />

    <script src="./lib/axios.js"></script>
    <script>
      const img = document.querySelector("img");
      const input = document.querySelector("input");
      input.addEventListener("change", function () {
        // this.files 数组形式
        console.log(this.files);
        const file = this.files[0];
        // 用URL对象 找到选择的文件的路径
        const src = URL.createObjectURL(file);
        img.src = src;
      });
    </script>
  </body>

formData()实现上传

  <body>
    <input type="file" accept="image/*,video/*" />
    <img src="" alt="找不到" />

    <script src="./lib/axios.js"></script>
    <script>
      const img = document.querySelector("img");
      const input = document.querySelector("input");
      input.addEventListener("change", function () {
        // this.files 数组形式
        console.log(this.files);
        const file = this.files[0];
        // 用URL对象 找到选择的文件的路径
        const src = URL.createObjectURL(file);
        img.src = src;

        // 创建空formData对象
        const formdata = new FormData();
        // 查看文档请求参数 avatar,对象, 将待上传文件加进空formData对象,接口要求
        formdata.append("avatar", file);
        axios
          .post("http://www.itcbc.com:3006/api/formdata", formdata)
          .then((result) => {
            console.log(result);
          });
      });
    </script>
  </body>

报文

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

url参数

  1. url长度有限制,参数大小不会太大

请求体

  1. 5种请求方式可以设置请求体
  2. 请求体大小没有限制,可以提交大量的数据
  3. 常用请求体格式
    1. 参数-值(字符串)
    2. "{'id': 1}"(JSON格式)
    3. new formData() (FormData对象)

http响应状态码

  • 2xx:成功
  • 3xx:重定向
  • 4xx:客户端错误
  • 5xx:服务器错误

http响应状态码,业务状态码区别:

  • 表示的结果不同
    • 响应状态码只能表示这次请求的成功与否
    • 业务状态码表示业务处理成功与否
  • 通用性不同
    • 响应状态码是由http协议规定,具有通用性
    • 业务状态码是后端程序员自定义,不具有通用性

原生Ajax

XMLHttpRequest()

浏览器内置的构造函数

作用:基于实例,发起Ajax请求

发起请求步骤(面试)

  1. 创建const xhr=new XMLHttpRequest()对象

    const xhr=new XMLHttpRequest()
    
  2. 调用xhr.open()函数

    xhr.open("get","http://www.itcbc.com:3006/api/getbooks")
    
  3. 调用xhr.send()函数

    xhr.send()
    
  4. 监听load事件

    xhr.addEventListener("load",function () {
                console.log(this.response);
                const obj=JSON.parse(this.response)
                console.log(obj);
            })
    

请求参数

  1. 拼接到url地址

    xhr.open("get","http://www.itcbc.com:3006/api/getbooks?appkey=1904050132")
    
  2. 传入send()方法

    xhr.send(data)
    

重点理解Ajax发送请求底层封装

  1. 判断传入的请求方式(get,post

  2. get,继续判断data类型

    1. 对象要转成参数格式进行拼接
    2. 已经是字符串就直接拼接url
  3. post,继续判断dataString,Object中的哪一种类型

    1. 是字符类型则直接使用xhr.send(data)
    2. 是对象,则继续判断是不是属于(instanceof)FormData()实例,是则xhr.send(data)
    3. 否则先用data=JSON.Stringify(data)转成字符串,接着xhr.send(data)
      <body>
        <input type="file" accept="image/*" />
        <script>
          // data为继承于FormData()对象
          const input = document.querySelector("input");
          input.addEventListener("change", function () {
            const file = this.files[0];
            const data = new FormData().append("avatar", file);
            const option1 = {
              url: "http://www.itcbc.com:3006/api/formdata",
              type: "post",
              data,
              success(result) {
                console.log(result);
              },
            };
            ajax(option1);
          });
    
    			//__________________________________
    
    			// data为字符串
          const option1 = {
            url: "http://www.itcbc.com:3006/api/formdata",
            type: "post",
            /* data: {
                bookname: "wuchengen",
                author: "tjm",
                publisher: "xinhuazidian",
                appkey: "1904050132",
              }, */
            data:"bookname=守护甜心&author=越前龙马&publisher=蜡笔小新",
            success(result) {
              console.log(result);
            },
          };
          ajax(option1);
    
    			// data为object普通对象
          const option1 = {
            url: "http://www.itcbc.com:3006/api/formdata",
            type: "post",
            /* data: {
                bookname: "wuchengen",
                author: "tjm",
                publisher: "xinhuazidian",
                appkey: "1904050132",
              }, */
            data:"bookname=守护甜心&author=越前龙马&publisher=蜡笔小新",
            success(result) {
              console.log(result);
            },
          };
          ajax(option1);
    
    
          // ajax底层封装
          function ajax({ url, type, data = "", success }) {
            const xhr = new XMLHttpRequest();
            // GET 请求方式
            if (type === "get") {
              // 继续判断data类型,为对象则转成参数格式再进行拼接
              if (typeof data === "object") {
                data = new URLSearchParams(data).toString();
              }
              xhr.open(type, url + "?" + data);
              xhr.send();
              // POST 请求方式
            } else if (type === "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") {
                if (data instanceof FormData) {
                  xhr.send(data);
                } else {
                  data = new URLSearchParams(data).toString();
                  xhr.setRequestHeader("Content-type", "application/json");
                  xhr.send(data);
                }
              }
            }
            xhr.addEventListener("load", function () {
              const obj = JSON.parse(this.response);
              success(obj);
            });
          }
        </script>
      </body>
    
    

防抖和节流

防止用户在搜索框或其他地方连续不断发送请求浪费性能

防抖

// 防抖延时器
      let timeid;
      userEnter.addEventListener("input", function (e) {
        // 一直输入就一直清除延时器,直到停止输入
        clearTimeout(timeid);
        timeid = setTimeout(() => {
          const value = this.value.trim();
          if (value) {
            const query = `?bookname=${value}`;
            getData(query);
            // this.value = "";
          } else {
            // 获取数据
            getData();
          }
        }, 2000);
      });

节流

btn.addEventListener("click", () => {
        // 点击结束,立即禁用按钮
        btn.disabled = true;
        getData();
      });
      // 获取数据单独封装一段代码
      // js高级-参数默认值
      function getData(query = "") {
        axios({
          method: "get",
          url: `http://www.itcbc.com:3006/api/getbooks` + query,
        }).then((result) => {
          const arr = result.data.data;
          render(arr);
          // 获取到响应数据,开启按钮
          btn.disabled = false;
        });
      }

同源策略&跨域

同源:2个URL地址具有相同协议、主机名、端口号

同源策略

  • 浏览器提供的一个安全功能
  • 规定:不允许非同源的URL之间进行资源的交互

跨域

  • 跨越不同源地址-跨域
  • 浏览器允许发起跨域请求,但跨域响应的数据会被浏览器拦截,无法被页面获取到
  • 突破跨域限制(2种方案)
    • JSONP(非官方):较早,兼容好,仅支持GET请求
    • CORS(W3C官方标准):较晚,支持常见请求方式,不兼容低版本浏览器,也是解决跨域数据请求的终极方案

CORS

需要浏览器和服务器同时支持

JSONP

可以把非同源的JavaScript代码请求到本地,并执行

如果请求回来的JS代码只包含函数的调用,则需要程序员手动定义show方法

Git(了解)

版本管理系统

  • 作用
    • 记录每次代码的变更,以便将来查阅特定版本的修改情况
    • 完成多人协作(必须配合远程仓库)
  • 管理软件的分类
    • 集中式(SVN)
    • 分布式(Git)
  • 集中式
    • 代码版本集中到一个服务器
    • 没有网络或者崩溃,无法进行版本管理
  • 分布式
    • 代码版本分布到每个计算机上
    • 99%的操作都是在自己的计算机上完成
    • 联网即可同步代码

三个区域

  • git内部实现,离不开维护的三个区域
    • 工作区(代码区)
    • 暂存区
    • 仓库

分支

  • git分支系统强大
  • 分支相当于项目副本
  • 初始化后,git默认创建一个master主分支
  • 实际开发中,企业不允许在主分支开发,会在分支上开发,最后将代码合并

冲突

  • 工作常见场景,合并同名文件时而发生

  • vscode合并冲突时会把冲突内容高亮显示

本地推送到远程仓库

  1. 码云地址新建远程仓库

  2. 在需要新建本地仓库的位置右键打开git终端

  3. 将远程仓库克隆到本地(将会弹出用户名密码输入框)

    git clone https://gitee.com/icarrot/rro.git
    
  4. 在本地仓库里面打开终端,新建一些文件

    touch index.js index.html index.css
    
  5. 文件添加进暂存区

    git add .
    
  6. 暂存区提交到本地仓库

    git commit -m "提交说明"
    
  7. 本地推送到远程仓库

    git push
    

拓展

  1. axiospost请求参数可以用字符串

    data:"bookname=守护甜心&author=越前龙马&publisher=蜡笔小新"
    
  2. axios请求方法可以简写(详细查看线上文档)

    axios.get()
    axios.post()
    axios.delete()
    axios.put()
    
  3. 拦截器(axios官方文档)——请求前拦截一下显示加载中效果,后端返回数据停止显示加载效果

    // 添加请求拦截器
          axios.interceptors.request.use(
            function (config) {
              // 在发送请求之前做些什么
              img.style.display="block"
              return config;
            },
            function (error) {
              // 对请求错误做些什么
              return Promise.reject(error);
            }
          );
    
          // 添加响应拦截器
          axios.interceptors.response.use(
            function (response) {
              // 2xx 范围内的状态码都会触发该函数。
              // 对响应数据做点什么
              img.style.display="none"
              return response;
            },
            function (error) {
              // 超出 2xx 范围的状态码都会触发该函数。
              // 对响应错误做点什么
              return Promise.reject(error);
            }
          );
    
    
  4. 谷歌浏览器网络调试工具提供了网速调节功能,可以调试需要慢慢加载的代码

  5. 免费API网站:聚合数据……