01-初识Ajax

89 阅读5分钟

初识Ajax

服务器相关的基础概念

服务器

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

服务器的作用

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

获取服务器的方式

  • 购买(京东、淘宝……)
  • 租赁(阿里云、腾讯云……)

资源

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

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

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

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

    id书名作者出版社
    1水浒传施耐庵北京出版社
    2三国演义罗贯中上海出版社
    3斗破苍穹天蚕土豆清华出版社
    4神墓辰东网络出版社
    5钢铁是怎样炼成的奥斯特洛夫斯基清华出版社

客户端

概念

在前端开发中,客户端特指“Web 浏览器”。

作用

互联网世界中的 Web 资源加载、并呈现到浏览器窗口中供用户使用。

1650790150787

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

URL 地址,表示服务器上每个资源的确切位置。

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

1650790213592

对数据的操作(增删改查),也对应着不同的URL地址

1650792936383

客户端与服务器通信

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

就像我们(客户)去银行(服务场所)办理业务:

  • 客户提出需求:客户提出要办理业务,比如办卡、存钱、取钱、销户、买纪念币等等
  • 银行的回应:银行根据客户的需求,办理相关的业务

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

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

1650850274523

Ajax

1.初识Ajax

什么是Ajax

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

1650850433663

这样的解释方式感觉有点抽象,让我们去了解一下日常生活中接触到的ajax,来加深一下我们的记忆跟理解。

生活中的Ajax

1650850460707

1650850553926

1650850565670

2.Ajax的请求方式

使用 Ajax 请求数据的 5 种方式

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

序号请求方式描述
1POST向服务器新增数据
2GET从服务器获取数据
3DELETE删除服务器上的数据
4PUT更新服务器上的数据(侧重于完整更新:例如更新用户的完整信息)
5PATCH更新服务器上的数据(侧重于部分更新:例如只更新用户的手机号)

(一) GET 请求

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

1650850803994

 <!-- 1 引入axios -->
    <script src="./lib/axios.js"></script>
    <script>
      // 1 打开页面  发送一个ajax 请求 获取数据 -  渲染页面
      getData();

      // 2 获取输入框
      const input = document.querySelector('input');
      input.addEventListener('keydown', function (event) {
        // 2.1 判断 按下的是不是回车键
        if (event.key === 'Enter') {
          // 2.2 获取输入框的值
          const value = this.value.trim(); // trim() 去除 输入框的值 的两侧的 空字符串
          // 2.3 判断是不是空字符串
          if (value) {
            // 不是空字符串
            console.log('不是空字符串');
            // bookname:"万少"
            // url 传参 ?属性名 = 属性值
            const queryStr = `?bookname=${value}`;
            // console.log(queryStr);
            getData(queryStr); // 把参数带过去
          } else {
            // 空字符串
            // console.log("空字符串");
            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>
        </tr>
      `
          )
          .join('');
        document.querySelector('tbody').innerHTML = html;
      }
    </script>

(二)POST 请求

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

1650850864249

<body>
    <button>加载一个数据</button>

    <script src="./lib/axios.js"></script>
    <script>
      const button = document.querySelector('button');
      button.addEventListener('click', function () {
        // 执行 post请求新新增数据
        axios({
          method: 'post', // post
          url: 'http://www.itcbc.com:3006/api/addbook', // url
          // 参数
          data: {
            // 这个里面 不能乱写 属性名和属性值
            // 乱写参数,如果后端因为你不按照规范出了错 你前端 也是背锅
            bookname: '从入门到精通',
            author: '我自己',
            publisher: '黑马出版社', // 想传递一个数字格式 不行 (我只能去对比代码看什么地方可能出错)
            // publisher: Date.now()+"",// 想传递一个数字格式 不行 (我只能去对比代码看什么地方可能出错)
          },
        }).then((result) => {
          // 去银行操作完毕之后  存钱 取钱  纸条 告诉我们  操作成功与否
          console.log(result);
        });
      });
    </script>
  </body>

(三)DELETE 请求

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

1650850927263

<!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>10-图书管理-删除</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');

      tbody.addEventListener('click', function (event) {
        if (event.target.className === 'del') {
          //  获取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(); // 删除成功了 重新显示页面数据
          });
        }
      });
      getData();
      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>

(四)PUT 请求

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

1650851016867

(五)PATCH 请求

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

1650851093997

3.Ajax的基础用法

通过原生代码,完全可以实现Ajax请求,为了第一天学习方便,我们选择使用 axios 库 原生代码后续学习

axios

axios(发音:艾克C奥斯) 是前端圈最火的、专注于数据请求的库。

1650851202041

在后面的 Vue、React 课程中都会用到 axios 来请求数据。

中文官网地址:www.axios-http.cn/

英文官网地址:www.npmjs.com/package/axi…

axios 的基础语法

1650851250820

基于 axios 发起 GET 请求

测试 GET 请求的 URL 地址为 www.itcbc.com:3006/api/getbook…

1650851310134

1650851338483

result是一个对象

result.data 才是服务器返回的结果

代码展示
 <!-- 1 引入axios -->
    <script src="./lib/axios.js"></script>
    <script>


/* 
1 资源的地址 问后端要即可 
2 我们负责用对 代码 确保 数据可以请求成功 
3 不需要纠结 result的数据格式 
      只需要打印出result ,在里面 resut.data 找到数据  
      自己截图数据
4 把数据 存在自己的一个数组中
5 使用以前教过知识把数组渲染到页面中 

 */
      axios({
        method: 'get',
        url: 'http://www.itcbc.com:3006/api/getbooks',
      }).then((result) => {
        console.log(result);
        // result 请求成功的结果
        // then 固定!! 是axios封装的一个代码  意思 服务器把数据返回了,then里面的代码就会被触发
        // 底层套了两层data 也是后台程序员做的,不用纠结 别人怎么定义的 我只负责如何拿对
        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>

GET 请求的查询参数

刚才查询回来的是所有图书的列表数据,如果想指定查询的条件,可以通过 params 选项来指定查询的参数

1650851666290

如果要携带多个参数,只需要在 params 对象中指定多个查询参数项即可。示例代码如下:

1650851641989

代码展示
  <script src="./lib/axios.js"></script>
    <script>
      /* 
    小结
    1 在实际开发过程种,我们可以在前端 指定参数来查询对应的数据 
    2 指定参数的 参数的代码写法 必须要写在
      params 对象中,以 键值对的形式存在
    3 params 对象中,写什么样的键值对 规定要由后端来决定  前端不懂的时候问他

       */
      axios({
        // 请求方式
        method: 'get',
        // 请求地址
        url: 'http://www.itcbc.com:3006/api/getbooks',
        // 请求的参数
        params: {
          // 固定
          // 键值对 是需要问后端程序员才知道
          // id:5913   // 后端就会返回 id为5913的那一条数据
          // bookname:"万少"// 后端就会返回 书名 为 万少的一堆数据
          // author:"王勇"// 如果你这么写 后端什么都不返回(规则后端制定 )

          // 在真实的开发场景中 往往会出现 前端以为我的代码参数都写对了 为什么没有结果
          // 后端程序员都没有写到那个功能 !

          // id:5913  // 根据id来查询数据  后端已经做好这个功能了

          // bookname: '万少',
          // author: '黑马',// 后端没有做这个功能
          publisher: '6666',// 后端没有做这个功能
        },
      }).then((result) => {
        console.log(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>
其他方式-指定参数-直接拼接参数

url:http://www.xxx?属性名=属性值&属性名=属性值

属性值为字符串时,不需要添加引号

 <script src="./lib/axios.js"></script>
    <script>
      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;
      }
    </script>
案例

1650853284460

思路分析

1650853294047

代码实现
<!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>1-显示完整数据</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>
    <!-- 1 引入axios -->
    <script src="./lib/axios.js"></script>
    <script>
      // 1 打开页面  发送一个ajax 请求 获取数据 -  渲染页面
      getData();

      // 2 获取输入框
      const input = document.querySelector('input');
      input.addEventListener('keydown', function (event) {
        // 2.1 判断 按下的是不是回车键
        if (event.key === 'Enter') {
          // 2.2 获取输入框的值
          const value = this.value.trim(); // trim() 去除 输入框的值 的两侧的 空字符串
          // 2.3 判断是不是空字符串
          if (value) {
            // 不是空字符串
            console.log('不是空字符串');
            // bookname:"万少"
            // url 传参 ?属性名 = 属性值
            const queryStr = `?bookname=${value}`;
            // console.log(queryStr);
            getData(queryStr); // 把参数带过去
          } else {
            // 空字符串
            // console.log("空字符串");
            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>
        </tr>
      `
          )
          .join('');
        document.querySelector('tbody').innerHTML = html;
      }
    </script>
  </body>
</html>

基于 axios 发起 POST 请求

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

1650860121889

POST 案例

添加图书

1650860156710

代码展示

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

接口的基础知识

接口的概念

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

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

接口文档

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

接口文档的格式

组成部分说明
接口名称接口的名称,用来快速区分每个接口的作用。如:登录接口、添加图书接口
接口 URL客户端发起 Ajax 调用此接口时,请求的 URL 地址
请求方式接口的请求方式,如:GET、POST、PUT、DELETE 等
请求参数请求此接口时,需要发送到服务器的查询参数或请求体
返回示例当接口请求成功后,服务器响应回来的数据的基本格式
返回参数说明接口响应结果的详细描述

Ajax课程案例接口文档 docs.apipost.cn/preview/f62…