当前位置: 首页 > article >正文

什么是 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 都指向一个唯一的资源:网页,图片,数据,视频,音频等等
    • 网页资源:黑马程序员官网-IT培训机构|java培训|前端培训|python培训|大数据培训|鸿蒙开发培训
    • 图片资源:https://www.itheima.com/images/logo.png
    • 数据资源:https://hmajax.itheima.net/api/province (Chrome浏览器勾选美观输出) https://hmajax.itheima.net/api/news

  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 如何携带查询参数?

  • 使用 params 选项即可
axios({
  url: 'http://测试服务器/资源路径',
  params: {
    key: 'value',
    key2: 'value2'
  }
}).then(res => {
  // 接受并使用数据
})

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 => {
  // 处理错误
})
  1. 对应代码
  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">
    <input type="text" name="username">
    <br>
    <input type="text" name="password">
    <br>
    <input type="button" class="btn" value="提交">
  </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>
  <div class="wrapper">
    <textarea id="tx" placeholder="发一条友善的评论" rows="2" maxlength="200"></textarea>
    <button>发布</button>
  </div>
  <div class="wrapper">
    <span class="total">0/200字</span>
  </div>
  <div class="list">
    <p>评论信息:</p>
    <p class="msg">善语结善缘~~请发表你的评论</p>

  </div>


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

http://www.kler.cn/a/467496.html

相关文章:

  • 【NLP高频面题 - 分布式训练篇】ZeRO主要为了解决什么问题?
  • 【C++】P2550 [AHOI2001] 彩票摇奖
  • ARM CCA机密计算安全模型之加密建议
  • SpringBoot中实现拦截器和过滤器
  • python对mongodb的增删查改
  • AI代码开发实践-微信小程序开发
  • CentOS7 使用yum报错:[Errno 14] HTTP Error 404 - Not Found 正在尝试其它镜像。
  • 【VScode】设置代理,通过代理连接服务器
  • 【CVPR 2024】【遥感目标检测】Poly Kernel Inception Network for Remote Sensing Detection
  • 【2025软考高级架构师】案例题重点知识——第三部分
  • 反直觉导致卡关-迫击炮谜题
  • unity学习4:git和SVN的使用差别
  • PHP语言的计算机基础
  • 探索最新的编程技术趋势:AI 编程助手和未来的编程方式
  • 瑞吉外卖项目学习笔记(十一)分页查询订单列表
  • 学习随笔:word2vec在win11 vs2022下编译、测试运行
  • CSP初赛知识学习计划
  • Spring Cloud Security集成JWT 快速入门Demo
  • kafka使用以及基于zookeeper集群搭建集群环境
  • 投稿指南【NO.12_14】【极易投中】期刊投稿(毛纺科技)
  • 敏捷开发中,每日站会应该怎么开?
  • 公共数据授权运营系统建设手册(附下载)
  • R 语言科研绘图第 13 期 --- 柱状图-堆叠
  • 使用 TensorFlow 打造企业智能数据分析平台
  • 【Leetcode】732. 我的日程安排表 III
  • Qlib量化回测安装以及使用