什么是 AJAX ?

什么是 AJAX ?

AJAX 是异步的 JavaScript 和 XML(Asynchronous JavaScript And XML)。

简单理解AJAX:是一种客户端与服务器进行网络通信技术,AJAX通常使用XMLHttpRequest 对象来发送请求和接收响应

现代开发中我们通常使用 JSON格式来进行数据的传输

为何学 AJAX?

  • 以前我们的数据都是写在代码里固定的, 无法随时变化
  • 现在我们的数据可以从服务器上进行获取,让数据变活

什么是Axios

Axios 是一个别人封装好的网络请求库,可以方便的让我们完成与服务器进行网络通讯。

浏览器端Axios是基于AJAJX对象XMLHttpRequest 来进行封装的

前端 开发和鸿蒙开发都需要到Axios

官网

什么是服务器?

在网络上提供服务器的一台电脑,比如提供数据服务

服务器接口文档

Axios基本用法

咱们来看看 Axios如何使用

axios官网

复制代码
// 1. 引入 axios.js 文件到自己的网页中
 <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.4/axios.min.js"></script>

// 2. 使用axios
    axios({
    url: '目标资源地址'
  }).then((res) => {
     // res是一个对象,保存了服务器返回的数据
     // ✨✨✔️其中:res.data 是保存了服务器的响应数据,我们经常使用它
  })

试一试:使用axios请求 https://api-vue-base.itheima.net/api/joke

获取一条随机笑话

实现效果:

点击【按钮】获取一条【随机的笑话】并【展示到页面】上

复制代码
<!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>AJAX概念和axios使用</title>
</head>

<body>
  <!--
    axios库地址:https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js
    省份数据地址:http://hmajax.itheima.net/api/province

    目标: 使用axios库, 获取省份列表数据, 展示到页面上
    1. 引入axios库
  -->
  <p class="my-p"></p>
  <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.4/axios.min.js"></script>
  <script>
    // 2. 使用axios函数
    axios({
      // url: 'http://hmajax.itheima.net/api/province'
      url:'https://api-vue-base.itheima.net/api/joke'
    }).then(result => {
      console.log(result)
      // 好习惯:多打印,确认属性名
      console.log(result.data)
      // console.log(result.data.list.join('<br>'))
      // 把准备好省份列表,插入到页面
      document.querySelector('.my-p').innerHTML = result.data
    })
  </script>
</body>

</html>

1. 认识URL

刚刚请求的地址url并不是随意的一些字符串,他叫做 URL,也可以叫做统一资源定位符

URL:统一资源定位符(Uniform Resource Locator),简称网址,用于定位网络中的资源

  • 每个有效的 URL 都指向一个唯一的资源:网页,图片,数据,视频,音频等等
  1. URL 的组成?
    • 协议,域名,资源路径(URL 组成有很多部分,我们先掌握这3个重要的部分即可)
  1. 什么是 http 协议 ?
    • 叫超文本传输协议,规定了浏览器和服务器传递数据的格式(而格式具体有哪些今天我们就会学到)
  1. 什么是域名 ?
    • 标记服务器在互联网当中的方位,网络中有很多服务器,你想访问哪一台,就需要知道它的域名才可以
  1. 什么是资源路径 ?
    • 一个服务器内有多个资源,资源路径用于标识你要访问的资源具体的位置

2. JSON

2.1. 基本概念

什么是JSON?

JSON 是一种按照 JavaScript 对象语法的数据格式,虽然它是基于 JavaScript 语法,但它独立于 JavaScript,许多【程序环境】能够读取(解读)和生成 JSON。

链接

JSON的作用?

JSON是一个**字符串,**常用于存储和传递数据

语法规则:

  1. 是一个字符串(配置文件中两边可以不写引号)

  2. 属性名用双引号包裹,

  3. 属性值如果是字符串也必须用双引号包裹

  4. 对象**{}** ,数组**[]**

    const jsonObj='{"name":"jack","age":18}'
    const arr = '["你好","西兰花炒蛋"]'
    const arrObj = '[{"name":"jack"},{"name":"rose"}]'

Axios默认在它的底层已经通过 JSON.parse()将服务器传过来的json字符串变成了js数据类型

2.2. JSON字符串转换

如果要在 JSON 和对象之间转换,就需要用到对应api 啦:(数组也是对象)

JSON.stringify(对象)// 转为 JSON

JSON.parse(JSON)

复制代码
// JSON.parse
const jsonObj='{"name":"jack","age":18}'
const obj =  JSON.parse(jsonObj)

const jsonArr = '["你好","西兰花炒蛋"]'
const arr= JSON.parse(jsonArr)

// JSON.stringify
const p={
  name:'rose',
  age:20
}

let jsonStr = JSON.stringify(p)

3. 案例-新闻

结合刚刚测试的获取新闻数据的 URL 地址,咱们来做一个案例:

需求:

  1. 打开页面时,使用axios 请求URL https://hmajax.itheima.net/api/news 获取新闻并渲染到页面上

3.1. 基础模板

复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }


        .box {
            padding: 5px;
        }
        .item {
            display: flex;
            padding: 10px;
            box-shadow: 1px 1px rgba(0,0,0,0.1);
            margin: 5px 0px;
        }

        .item img {
            width: 104px;
            height: 78px;
            border-radius: 5px;
        }

        .item h3 {
            font-size: 16px;
            font-weight: 500;
            height: 40px;
            line-height: 20px;
            overflow: hidden;
        }

        .left div span {
            font-size: 12px;
        }

        .left div {
            margin-top: 10px;
        }
    </style>
</head>

<body>
    <div class="box">
        <div class="item">
            <div class="left">
                <h3>一抓一放、张手就来:华为Mate 70/X6
                    系列手机、MatePad Pro 13.2 英寸平板 2..</h3>
                <div>
                    <span>新京报  2024-12-7 09:17:02</span>
                    <span>94评</span>
                </div>
            </div>
            <img src="https://img.ithome.com/newsuploadfiles/thumbnail/2024/11/812592_240.jpg" alt="">
        </div>
    </div>
</body>

</html>

3.2. 完整代码

复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }


        .box {
            padding: 5px;
        }
        .item {
            display: flex;
            padding: 10px;
            box-shadow: 1px 1px rgba(0,0,0,0.1);
            margin: 5px 0px;
        }

        .item img {
            width: 104px;
            height: 78px;
            border-radius: 5px;
        }

        .item h3 {
            font-size: 16px;
            font-weight: 500;
            height: 40px;
            line-height: 20px;
            overflow: hidden;
        }

        .left div span {
            font-size: 12px;
        }

        .left div {
            margin-top: 10px;
        }
    </style>
</head>

<body>
    <div class="box">
      <!-- <div class="item">
            <div class="left">
                <h3>一抓一放、张手就来:华为Mate 70/X6
                    系列手机、MatePad Pro 13.2 英寸平板 2..</h3>
                <div>
                    <span>新京报  2024-12-7 09:17:02</span>
                    <span>94评</span>
                </div>
            </div>
            <img src="https://img.ithome.com/newsuploadfiles/thumbnail/2024/11/812592_240.jpg" alt="">
        </div> -->
    </div>

    <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.4/axios.min.js"></script>
    <script>
       axios({     
      url:'https://hmajax.itheima.net/api/news'
    }).then(result => {
      console.log(result)
      // 好习惯:多打印,确认属性名
      console.log(result.data.data)
      let str = ``
      result.data.data.forEach(item=>{
        str+=`
         <div class="item">
            <div class="left">
                <h3>${item.title}</h3>
                <div>
                    <span>${item.source}  ${item.time}</span>
                    <span>${item.cmtcount}评</span>
                </div>
            </div>
            <img src="${item.img}" alt="">
        </div>
        `
      })

      // 把准备好省份列表,插入到页面
      document.querySelector('.box').innerHTML = str
    })
    </script>
</body>

</html>

4. URL 查询参数

目前咱们只能获取固定的数据,如果要查询特定的数据怎么办呢?可以通过 URL 查询参数来实现

4.1. 什么是URL查询参数

URL查询参数是提供给网络服务器的额外参数。这些参数是用 & 符号分隔的键/值对列表。在返回资源之前,Web 服务器可以使用这些参数来执行额外的操作。每个 Web 服务器都有自己关于参数的规则,唯一可靠的方式来知道特定 Web 服务器是否处理参数是通过询问 Web 服务器所有者

简而言之: 携带给服务器额外信息,让服务器返回我想要的某一部分数据而不是全部数据

咱么先通过 2 个预先准备好的地址来确认一下

百度安全验证

百度安全验证

百度安全验证

拼接在 URL 末尾的就是查询参数:

? 隔开之后使用&分隔的键值对列表

4.2. 如何确认 URL 查询参数

实际开发时,服务器的所有者会提供 URL 查询参数的信息,比如

地址: http://hmajax.itheima.net/api/city

说明获取某个省所有的城市查询

**参数名:**pname

**说明:**传递省份或直辖市名,比如 北京、广东省...

接口说明地址

4.3. axios 如何携带查询参数?

4.4. 城市查询案例(讲解)

url地址: http://hmajax.itheima.net/api/city

说明获取某个省所有的城市查询

**参数名:**pname

**说明:**传递省份或直辖市名,比如 北京、广东省...

接口说明地址

复制代码
<!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>AJAX概念和axios使用</title>
</head>

<body>
    <input type="text" class="pname" placeholder="输入如:广东省"> <button class="query">查询城市</button>
    <p class="my-p"></p>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.4/axios.min.js"></script>
    <script>

        document.querySelector('.query').addEventListener('click', function () {
            let pname = document.querySelector('.pname').value
            // 2. 使用axios函数
            axios({
                // url: 'http://hmajax.itheima.net/api/city?pname='+pname,
                url: 'http://hmajax.itheima.net/api/city',
                params:{
                    pname:pname
                }
            }).then(result => {
                console.log(result)
                // 好习惯:多打印,确认属性名
                console.log(result.data)
                // console.log(result.data.list.join('<br>'))
                // 把准备好省份列表,插入到页面
                document.querySelector('.my-p').innerHTML = result.data.list.join('<br>')
            })
        })


    </script>
</body>

</html>

4.5. 案例-查询-地区列表(自己写)

需求:根据输入的省份名字和城市名字,查询下属地区列表

服务器接口文档

查询地区: http://hmajax.itheima.net/api/area

参数名:

pname:省份名字

cname:城市名字

复制代码
<!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>AJAX概念和axios使用</title>
</head>

<body>
    <input type="text" class="pname" placeholder="输入如:广东省"> 
    <input type="text" class="cname" placeholder="输入如:深圳市"> 
    <button class="query">查询地区</button>
    <p class="my-p"></p>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.4/axios.min.js"></script>
    <script>

        document.querySelector('.query').addEventListener('click', function () {
            let pname = document.querySelector('.pname').value
            let cname = document.querySelector('.cname').value
            // 2. 使用axios函数
            axios({
                url: 'http://hmajax.itheima.net/api/area',
                params:{
                    pname:pname,
                    cname:cname
                }
            }).then(result => {
                console.log(result)
                // 好习惯:多打印,确认属性名
                console.log(result.data)
                // console.log(result.data.list.join('<br>'))
                // 把准备好省份列表,插入到页面
                document.querySelector('.my-p').innerHTML = result.data.list.join('<br>')
            })
        })


    </script>
</body>

</html>

5. 请求方法和数据提交

到目前为止都是向服务器获取数据,接下来咱们来看看如何向服务器发送数据

  1. GET请求方法是axios的默认请求方法
  2. 向服务器发送数据我们常用的方式是POST请求方法(需要显示指定)

提交数据给服务器的场景:用户登录,注册,修改密码等

5.1. Axios POST请求方法

复制代码
// ✨✨需要设置method 和 data 这2个新的选项
axios({
  url:'请求URL',
  method:'post',
  data:{
    key:'value',
    key1:'value1',
    .....
  },
})

5.2. POST请求举例

使用axios的post请求实现用户注册

测试用 url

请求地址(url):http://hmajax.itheima.net/api/register

注册用户

请求方法:POST

参数:username,password

说明:username 用户名(中英文和数字组成, 最少8位),password 密码(最少6位)

复制代码
<!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>常用请求方法和数据提交</title>
</head>

<body>
  <button class="btn">注册用户</button>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script>
    /*
      注册用户:http://hmajax.itheima.net/api/register
      请求方法:POST
      参数名:
        username:用户名(中英文和数字组成,最少8位)
        password:密码  (最少6位)

      目标:点击按钮,通过axios提交用户和密码,完成注册
    */
    document.querySelector('.btn').addEventListener('click', () => {
      axios({
        url: 'http://hmajax.itheima.net/api/register',
        method: 'POST',
        data: {
          username: 'itheima521',
          password: '12345678'
        }
      })
      .then(res=>{
        console.log(res.data);
        
      })
    })
  </script>
</body>

</html>

5.3. axios 错误处理

  1. 如果注册相同的用户名,则会遇到注册失败的请求,也就是 axios 请求响应失败了,你会在控制台看到如图的错误:

  2. 在 axios 语法中要如何处理呢?

    • 因为,普通用户不会去控制台里看错误信息,我们要编写代码拿到错误并展示给用户在页面上
  1. 使用 axios 的 catch 方法,捕获这次请求响应的错误并做后续处理,语法如下:

    axios({
    // 请求选项
    }).then(res => {
    // 处理数据
    }).catch(err => {
    // 处理错误
    })

  2. 对应代码

    document.querySelector('.btn').addEventListener('click', function () {
    // console.log('点了')
    // 通过axios提交用户数据,完成用户注册
    axios({
    url: 'http://hmajax.itheima.net/api/register',
    method: 'post',
    data: {
    username: 'itheima521',
    password: '123456'
    }
    }).then(res => {
    console.log(res.data)
    }).catch(err => {
    // 重复注册,通过弹框提示用户
    // console.log(err)
    // console.log(err.response.data)
    alert(err.response.data.message)
    })
    })

6. 接口文档

到目前为止,咱们请求的 URL 地址,请求的方法都是直接提供好了,日常开发中如何获取这些信息呢?

日常开发中一般通过【接口文档】来获取这部分信息,【接口文档】一般由后端工程师编写

咱们通过接口文档和服务器通讯这个操作,也可以叫做 【调接口】

接口文档1

接口文档2

6.1. 接口文档实践(登录)

咱们结合 登录-form 接口来完成用户登录,关注红色部分

接口文档2

复制代码
<!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>案例_登录</title>
  <!-- 引入bootstrap.css -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css">
  <!-- 公共 -->
  <style>
    html,
    body {
      background-color: #EDF0F5;
      width: 100%;
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
    }

    .container {
      width: 520px;
      height: 540px;
      background-color: #fff;
      padding: 60px;
      box-sizing: border-box;
    }

    .container h3 {
      font-weight: 900;
    }
  </style>
  <!-- 表单容器和内容 -->
  <style>
    .form_wrap {
      color: #8B929D !important;
    }

    .form-text {
      color: #8B929D !important;
    }
  </style>
  <!-- 提示框样式 -->
  <style>
    .alert {
      transition: .5s;
      opacity: 0;
    }

    .alert.show {
      opacity: 1;
    }
  </style>
</head>

<body>
  <div class="container">
    <h3>欢迎-登录</h3>
    <!-- 登录结果-提示框 -->
    <div class="alert alert-success" role="alert">
      提示消息
    </div>
    <!-- 表单 -->
    <div class="form_wrap">
      <form>
        <div class="mb-3">
          <label for="username" class="form-label">账号名</label>
          <input type="text" class="form-control username">
        </div>
        <div class="mb-3">
          <label for="password" class="form-label">密码</label>
          <input type="password" class="form-control password">
        </div>
        <button type="button" class="btn btn-primary btn-login"> 登 录 </button>
      </form>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script>
    // 目标1:点击登录时,用户名和密码长度判断,并提交数据和服务器通信
   
</body>

</html>

<!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>案例_登录</title>
  <!-- 引入bootstrap.css -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css">
  <!-- 公共 -->
  <style>
    html,
    body {
      background-color: #EDF0F5;
      width: 100%;
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
    }

    .container {
      width: 520px;
      height: 540px;
      background-color: #fff;
      padding: 60px;
      box-sizing: border-box;
    }

    .container h3 {
      font-weight: 900;
    }
  </style>
  <!-- 表单容器和内容 -->
  <style>
    .form_wrap {
      color: #8B929D !important;
    }

    .form-text {
      color: #8B929D !important;
    }
  </style>
  <!-- 提示框样式 -->
  <style>
    .alert {
      transition: .5s;
      opacity: 0;
    }

    .alert.show {
      opacity: 1;
    }
  </style>
</head>

<body>
  <div class="container">
    <h3>欢迎-登录</h3>
    <!-- 登录结果-提示框 -->
    <div class="alert alert-success" role="alert">
      提示消息
    </div>
    <!-- 表单 -->
    <div class="form_wrap">
      <form>
        <div class="mb-3">
          <label for="username" class="form-label">账号名</label>
          <input type="text" class="form-control username">
        </div>
        <div class="mb-3">
          <label for="password" class="form-label">密码</label>
          <input type="password" class="form-control password">
        </div>
        <button type="button" class="btn btn-primary btn-login"> 登 录 </button>
      </form>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script>
    // 目标1:点击登录时,用户名和密码长度判断,并提交数据和服务器通信
    
    // 1.1 登录-点击事件
    document.querySelector('.btn-login').addEventListener('click', () => {
      // 1.2 获取用户名和密码
      const username = document.querySelector('.username').value
      const password = document.querySelector('.password').value
      // console.log(username, password)

      // 1.3 判断长度
      if (username.length < 8) {
        console.log('用户名必须大于等于8位')
        return // 阻止代码继续执行
      }
      if (password.length < 6) {
        console.log('密码必须大于等于6位')
        return // 阻止代码继续执行
      }

      // 1.4 基于axios提交用户名和密码
      // console.log('提交数据到服务器')
      axios({
        url: 'http://hmajax.itheima.net/api/login',
        method: 'POST',
        data: {
          username,
          password
        }
      }).then(result => {
        console.log(result)
        console.log(result.data.message)
      }).catch(error => {
        console.log(error)
        console.log(error.response.data.message)
      })
    })
  </script>
</body>

</html>

7. HTTP协议

HTTP协议规定了【客户端发送的内容】及【服务器返回内容】的【格式】

咱们使用axios和服务器通讯的时候,本质上是发送和接收了符合 HTTP 协议规定的内容,接下来咱们来看看内容长啥样

7.1. 请求报文

请求报文:浏览器按照HTTP协议要求的格式,发送给服务器的内容

请求报文的组成部分:

  1. 请求行:请求方法,URL,协议(第一行)
  2. 请求头:以键值对的格式携带的附加信息,比如:Content-Type(第二行开始到空行)
  3. 空行:分隔请求头,空行之后的是发送给服务器的资源(空行)
  4. 请求体:发送的资源(空行之后)

学会请求报文的查看,可以帮助我们来进行排错

7.2. 响应报文

响应报文:服务器按照HTTP协议要求的格式,返回给浏览器的内容

响应报文组成:

  1. 响应行(状态行):协议、HTTP响应状态码、状态信息(第一行)
  2. 响应头:以键值对的格式携带的附加信息,比如:Content-Type(第一行到空行)
  3. 空行:分隔响应头,空行之后的是服务器返回的资源(空行)
  4. 响应体:返回的资源(空行之后)

咱们一般需要关注,响应行,响应体即可

不同于请求报文,响应报文是由服务器返回的,咱们无法修改,根据响应报文提供的信息,做出处理即可

响应行中可以获取到状态码,用来表示请求是否成功完成。

重点:

  1. http 模块基于 HTTP 协议进行通讯
  2. HTTP 协议:规定了提交的【数据格式】,以及响应的数据格式
    1. 提交的:请求报文
      1. 请求行(方法,地址)
      2. 请求头(Content-Type,提交的数据类型)
      3. 空行
      4. 请求体(提交的数据)
    1. 响应的:响应报文
      1. 响应行
      2. 响应头
      3. 空行
      4. 响应体

7.3. 面试题总结:

  1. 响应状态码404,500,304,307(302),200这些状态码分别代表什么意思?
    1. 404表示请求路径不存在 , 可能是url写错了,或者method写错了
    2. 500表示服务器处理异常,可能是我们没有按照规定的请求参数提供好必要的参数
    3. 304表示资源被缓存了,这个时候此资源不需要服务器重新返回,从浏览器直接返回
    4. 307(302) url重定向,表示当前请求的url需要重新定向到其他url才能正常访问到数据
    5. 200 表示成功响应
  1. 请你说一下请求头和响应头中的Content-Type代表什么意思?

    1. 请求头里面的Content-Type 表示客户端发送什么数据格式给服务器,服务器会根据此格式进行响应的数据解析
      1. applictaion/json
        1. 请求体的数据格式是一个json格式 {"key":"value","key1":"value1"}
      1. applictaion/x-www-form-urlencoded
        1. 请求体的数据格式是一个字符串 key=value&key1=value1.....
      1. application/multipart/form-data
        1. 通用用来做文件上传的时候专用的
    1. 响应头里面的Content-Type表示服务器发送什么数据格式给客户端(浏览器),客户端根据具体的格式来进行响应的解析
      1. 我们ajax里面常用的格式是: application/json
      2. 其他格式:
        1. text/html -> 表示是一个html网页
        2. image/png image/jepg image/gif -> 表示是一个图片
        3. text/plain ->表示返回的是一个普通字符串
        4. application/javascript -> 表示返回的是一个js文件
        5. ........

8. form-serialize 插件

  1. 我们前面收集表单元素的值,是一个个标签获取的
  2. 如果一套表单里有很多很多表单元素,如何一次性快速收集出来呢?
  3. 使用 form-serialize 插件提供的 serialize 函数就可以办到
  4. form-serialize 插件语法:
    • 引入 form-serialize 插件到自己网页中

    • 📎form-serialize.js 下载到项目lib文件夹中

      <script src="./lib/form-serialize.js"></script>
    • 使用 serialize 函数

      <form action="javascript:;" class="example-form">

      </form>

      /**
      * 2. 使用serialize函数,快速收集表单元素的值
      * 参数1:要获取哪个表单的数据
      * 表单元素设置name属性,值会作为对象的属性名
      * 建议name属性的值,最好和接口文档参数名一致
      * 参数2:配置对象
      * hash 设置获取数据结构
      * - true:JS对象(推荐)一般请求体里提交给服务器
      * - false: 查询字符串
      * empty 设置是否获取空值
      * - true: 获取空值(推荐)数据结构和标签结构一致
      * - false:不获取空值
      */
      const form = document.querySelector('.example-form')
      const data = serialize(form, { hash: true, empty: true })

8.1. 使用serialize插件重写登录页面

复制代码
<!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>案例_登录</title>
    <!-- 引入bootstrap.css -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css">
    <!-- 公共 -->
    <style>
        html,
        body {
            background-color: #EDF0F5;
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .container {
            width: 520px;
            height: 540px;
            background-color: #fff;
            padding: 60px;
            box-sizing: border-box;
        }

        .container h3 {
            font-weight: 900;
        }
    </style>
    <!-- 表单容器和内容 -->
    <style>
        .form_wrap {
            color: #8B929D !important;
        }

        .form-text {
            color: #8B929D !important;
        }
    </style>
    <!-- 提示框样式 -->
    <style>
        .alert {
            transition: .5s;
            opacity: 0;
        }

        .alert.show {
            opacity: 1;
        }
    </style>
</head>

<body>
    <div class="container">
        <h3>欢迎-登录</h3>
        <!-- 登录结果-提示框 -->
        <div class="alert alert-success" role="alert">
            提示消息
        </div>
        <!-- 表单 -->
        <div class="form_wrap">
            <form class="form">
                <div class="mb-3">
                    <label for="username" class="form-label">账号名</label>
                    <input type="text" name="username" class="form-control username">
                </div>
                <div class="mb-3">
                    <label for="password" class="form-label">密码</label>
                    <input type="password" name="password" class="form-control password">
                </div>
                <button type="button" class="btn btn-primary btn-login"> 登 录 </button>
            </form>
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script src="./lib/form-serialize.js"></script>
    <script>
        // 目标1:点击登录时,用户名和密码长度判断,并提交数据和服务器通信
        // https://hmajax.itheima.net/api/login
         // 收集用户输入的数据
        

        document.querySelector('.btn-login').addEventListener('click', function () {
            // let username = document.querySelector('.username').value
            // let password = document.querySelector('.password').value
            const form = document.querySelector('.form')
            let body =  serialize(form,{hash:true,empty:true})
            // console.log(body);
            // return 

            axios({
                url: 'https://hmajax.itheima.net/api/login',
                method: 'POST',
                data:body
                // data: {
                //     username: username,
                //     password: password
                // }
            })
                .then(res => {
                    // console.log(res.data)

                    // 当状态为200的时候,会执行.then里面的回调函数
                    // 根据文档 code如果为10000则表示成功,10004表示用户名和密码有问题
                    if (res.data.code == 10000) {
                        alert('登录成功')
                    } else {
                        alert(res.data.message)
                    }

                    //    if(res.data.code == 10004){
                    //     alert(res.data.message)
                    //    }

                })
                .catch(err => {
                    // 当状态非200的时候,会执行.then里面的回调函数
                    alert(err.response.data.message)

                })
        })

    </script>
</body>

</html>

9. 综合案例练习

  1. 页面进入的时候从服务器获取评论数据显示:接口文档

    <!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>回车发布评论案例</title> <style> .wrapper { width: 800px; display: flex; justify-content: flex-end; }
    复制代码
     .wrapper textarea {
       height: 50px;
       flex: 1;
       padding: 10px;
       border-radius: 4px;
       border-color: #e4e4e4;
       background: #fff;
       outline: none;
       resize: none;
     }
    
     .wrapper button {
       width: 70px;
       margin-left: 10px;
       border: none;
       color: #fff;
       background: #00aeec;
       border-radius: 4px;
       cursor: pointer;
     }
    
     .wrapper .total {
       margin-right: 80px;
       margin-top: 5px;
       color: #999;
     }
    
     .list {
       width: 800px;
       border: 1px solid #efce9c;
       background-color: rgb(231, 238, 191);
       padding: 10px;
     }
    
     .list p {
       font-size: 12px;
     }
    
     .msg {
       height: 20px;
       background-color: rgb(187, 249, 248);
     }
    </style> </head> <body>
    <textarea id="tx" placeholder="发一条友善的评论" rows="2" maxlength="200"></textarea> <button>发布</button>
    0/200字

    评论信息:

    善语结善缘~~请发表你的评论

    <script src="./lib/axios.js"></script> <script>
    复制代码
     // 1. 获取评论方法
     function getList() {
       axios({
         url: 'https://hmajax.itheima.net/api/cmtlist',
         params: {
           page: 1
         }
       })
         .then(res => {
           let dataList = res.data.data
           let str = ''
           dataList.forEach(item => {
             str += ` <p data-id="${item.id}" class="msg">${item.content}</p>`
           })
           document.querySelector('.list').innerHTML = str
         })
         .catch(err=>{
           alert(err.response.data.message)
         })
     }
    
    
     // 2. 初始化新增数据
     function initpublishData() {
       const textBox = document.querySelector('#tx')
       textBox.addEventListener('keyup', function (e) {
         if (e.key === 'Enter') {
           axios({
             url:'https://hmajax.itheima.net/api/addcmt',
             method:'POST',
             data:{
               username:'ivan',
               content:textBox.value
             }
           }).then(res=>{
             textBox.value = ''
             // 当发表一条新评论,则重新问服务器要最新数据回来显示在页面上
             getList()
           })
           .catch(err=>{
             alert(err.response.data.message)
           })
           
         }
       })
     }
     
     // 3. 删除指定数据
     function initDelData(){
       document.querySelector('.list').addEventListener('click',function(e){
         if(e.target.tagName === 'P'){
           let id = e.target.dataset.id
           axios({
             url:'https://hmajax.itheima.net/api/delcmt',
             params:{
               id:id
             }
           })
           .then(res=>{
             // 删除成功后,问服务器要删除以后的数据
             getList()
           })
           .catch(err=>{
             alert(err.response.data.message)
           })
         }
       })
     }
    
    // 调用方法
     getList()
     initpublishData()
     initDelData()
    </script> </body> </html>
相关推荐
你要飞1 小时前
Hexo + Butterfly 博客添加 Live2D 看板娘指南
笔记
ajsbxi5 小时前
【Java 基础】核心知识点梳理
java·开发语言·笔记
呱呱巨基5 小时前
vim编辑器
linux·笔记·学习·编辑器·vim
新子y5 小时前
【小白笔记】普通二叉树(General Binary Tree)和二叉搜索树的最近公共祖先(LCA)
开发语言·笔记·python
聪明的笨猪猪5 小时前
Java JVM “调优” 面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
爱学习的uu5 小时前
CURSOR最新使用指南及使用思路
人工智能·笔记·python·软件工程
YuCaiH5 小时前
Linux文件处理
linux·笔记·嵌入式
Cathy Bryant6 小时前
大模型损失函数(二):KL散度(Kullback-Leibler divergence)
笔记·神经网络·机器学习·数学建模·transformer
qq_398586546 小时前
Threejs入门学习笔记
javascript·笔记·学习
hour_go7 小时前
TCP/IP协议相关知识点
网络·笔记·网络协议·tcp/ip