一、简介
AJAX(Asynchronous JavaScript and XML)是一种使用现有标准的新方法。它是一种用于创建快速动态网页的技术。AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。AJAX 不需要任何浏览器插件,但需要用户允许 JavaScript 在浏览器上执行
1.1什么是 AJAX
AJAX = 异步 JavaScript 和 XML。
AJAX 是一种用于创建快速动态网页的技术。
通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面
1.2AJAX 工作原理
1.3应用场景
- 表单验证:使用 AJAX 可以在客户端进行表单验证,减少不必要的服务器开销。
- 动态加载内容:使用 AJAX 可以动态地向页面中添加内容,而无需重新加载整个页面。
- 设置联想词功能:使用 AJAX 可以根据用户输入自动完成搜索框联想词。
- 按需取数据:在 web 应用中,经常会用到分类树或树形结构,例如部门结构、文件的分类结构等。AJAX 技术可以实现树形结构,只获取第一级子分类的数据并显示,当用户点开一级分类的第一节点时,页面会通过 AJAX 向服务器请求当前分类所属的二级子分类的所有数据。如果再请求已经呈现的二级分类的某一节点时,再次向服务器请求当前分类所属的三级子分类的所有数据,以此类推。页面会根据用户的操作向服务器请求所需要的数据,这样就不会存在数据的冗余,减少了数据下载总量。同时,更新页面时不需要重新加载全部内容,只更新需要更新的那部分内容即可,大大缩短了用户的等待时间.
- 自动更新页面:web 应用中有很多数据的变化是实时的,例如最新的新闻、天气预报以及聊天室等等。使用 AJAX 技术可以改善这种情况,页面加载以后,会通过 AJAX 在后台进行定时的轮询,向服务器发送请求,查看是否有最新的消息。如果有,则将新的数据下载并且在页面上进行动态更新,通过一定的方式通知用户
1.4示例演示
<!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.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>// 2. 使用axios函数axios({url: 'http://hmajax.itheima.net/api/province'}).then(result => {console.log(result)// 好习惯:多打印,确认属性名console.log(result.data.list)console.log(result.data.list.join('<br>'))// 把准备好省份列表,插入到页面document.querySelector('.my-p').innerHTML = result.data.list.join('<br>')// 将 result 对象的 data 属性中的 list 属性打印到控制台,并将 list 中的元素用 <br> 标签连接起来,然后将连接后的字符串插入// 到页面中类名为 .my-p 的元素内。})
</script>
</body></html>
二、AJAX语法
2.1URL是什么
URL(Uniform Resource Locator)是一种字符串,用于标识互联网上的资源的位置12。它是一种用于定位和访问互联网上资源的标准格式。URL 通常由三部分组成:协议、主机名和路径。例如,https://www.bing.com/search?q=URL 中,https 是协议,www.bing.com 是主机名,search?q=URL 是路径
2.2 URL查询参数
查询参数是 URL 中的一部分,用于向服务器发送信息. 查询参数通常以 ? 开头,后跟一个或多个键值对,键和值之间用 = 分隔,不同键值对之间用 & 分隔 例如,在 https://www.bing.com/search?q=URL 中,查询参数为 q=URL
<!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">
</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.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>// 2. 使用axios函数axios({url: 'http://hmajax.itheima.net/api/city',params:{pname:'黑龙江省'}}).then(result => {console.log(result)// 好习惯:多打印,确认属性名console.log(result.data.list)console.log(result.data.list.join('<br>'))// 把准备好省份列表,插入到页面document.querySelector('.my-p').innerHTML = result.data.list.join('<br>')// 将 result 对象的 data 属性中的 list 属性打印到控制台,并将 list 中的元素用 <br> 标签连接起来,然后将连接后的字符串插入// 到页面中类名为 .my-p 的元素内。})
</script>
</body></html>
2.3axios是什么
Axios 是一个基于 JavaScript 的 HTTP 客户端,用于在浏览器和 Node.js 中发送异步请求。它是一个基于 Promise 的库,可以用于处理 HTTP 请求和 响应。
Axios 可以在浏览器中使用 XMLHttpRequests,在服务器端使用 Node.js http 模块。它提供了许多功能,包括从浏览器中进行 XMLHttpRequests 请求、支持 Promise API、拦截请求和响应、转换请求和响应数据、取消请求、自动转换 JSON 数据等
<!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>04.案例_地区查询</title><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"><style>:root {font-size: 15px;}body {padding-top: 15px;}</style>
</head><body>
<div class="container"><form id="editForm" class="row"><!-- 输入省份名字 --><div class="mb-3 col"><label class="form-label">省份名字</label><input type="text" value="北京" name="province" class="form-control province" placeholder="请输入省份名称" /></div><!-- 输入城市名字 --><div class="mb-3 col"><label class="form-label">城市名字</label><input type="text" value="北京市" name="city" class="form-control city" placeholder="请输入城市名称" /></div></form><button type="button" class="btn btn-primary sel-btn">查询</button><br><br><p>地区列表: </p><ul class="list-group"><!-- 示例地区 --><li class="list-group-item">东城区</li></ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>/*获取地区列表: http://hmajax.itheima.net/api/area查询参数:pname: 省份或直辖市名字cname: 城市名字*/// 目标: 根据省份和城市名字, 查询地区列表// 1. 查询按钮-点击事件document.querySelector('.sel-btn').addEventListener('click', () => {// 2. 获取省份和城市名字let pname = document.querySelector('.province').valuelet cname = document.querySelector('.city').value// 3. 基于axios请求地区列表数据axios({url: 'http://hmajax.itheima.net/api/area',params: {pname,cname}}).then(result => {// console.log(result)// 4. 把数据转li标签插入到页面上let list = result.data.listconsole.log(list)let theLi = list.map(areaName => `<li class="list-group-item">${areaName}</li>`).join('')console.log(theLi)document.querySelector('.list-group').innerHTML = theLi})})
</script>
</body></html>
2.4常用请求方法和数据提交
常用请求方法
axios请求数据
axios({url: '目标资源地址',method: '请求方法',data: {参数名: 值}}).then(result => {// 对服务器返回的数据做后续处理})
<!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>05.常用请求方法和数据提交</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: 'yanyu0712',password: '7654321'}}).then(result=>{console.log(result)})})
</script>
</body></html>
2.5axios错误处理
<!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>05.常用请求方法和数据提交</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: 'yanyu0712',password: '7654321'}}).then(result=>{console.log(result)}).catch(error => {// 失败// 处理错误信息console.log(error)console.log(error.response.data.message)alert(error.response.data.message)})})
</script>
</body></html>
2.6HTTP 协议-请求报文
HTTP 请求报文是在应用程序之间发送的数据块,用于 HTTP 协议交互。请求端(客户端)的 HTTP 报文叫做请求报文,响应端(服务器端)的叫做响应报文。HTTP 报文本身是由多行数据构成的字符串文本
一个 HTTP 请求报文由四个部分组成:请求行、请求头部、空行和请求体
GET /index.html HTTP/1.1 Host: www.example.com User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Referer: https://www.google.com/
- 请求行包含了请求方法、URL 和协议版本。
- 请求头部包含了一系列属性,如 User-Agent、Accept 和 Referer,用于告知服务器有关客户端的信息。
- 空行用于分隔请求头部和请求体。
- 请求体包含了实际的请求数据,如表单字段等。
2.7HTTP 协议-响应报文
HTTP 响应报文是指服务器在接收到客户端的 HTTP 请求后,返回给客户端的报文。它由四个部分组成:响应行、响应头部、空行和响应体
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 138
Date: Sat, 23 Sep 2023 12:43:55 GMT<!DOCTYPE html>
<html>
<head><title>Example Page</title>
</head>
<body><h1>Hello, World!</h1>
</body>
</html>
- 响应行包含了协议版本、状态码和状态描述。
- 响应头部包含了一系列属性,如 Content-Type、Content-Length 和 Date,用于告知客户端有关响应的信息。
- 空行用于分隔响应头部和响应体。
- 响应体包含了实际的响应数据,如 HTML 页面内容。
2.8接口文档
接口文档是用于描述系统所提供接口信息的一种说明文档。在项目开发中,web项目是前后端分离开发的,APP开发,需要由前后端工程师共同定义接口,编写接口文档,之后大家都根据这个接口文档进行开发,到项目结束前都要一直维护。接口文档应当包括以下内容:
- 接口简介: 描述接口的功能和用途。
- 定义请求协议: 描述请求协议的类型,如HTTP、HTTPS、FTP等。
- 请求地址源: 描述请求地址的来源。
- 请求方式: 描述接口的功能和使用方法。
- 请求参数: 描述请求参数的格式和内容。
- 返回参数示例: 描述如何判断接口是否收到了请求,并且返回了正确的结果。
- 状态码: 用于快速向请求方反馈当前请求的处理结果
三、案例分析--用户登录
登录实现
<!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>11.案例_登录</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" id="username">账号名</label><input type="text" class="form-control username"></div><div class="mb-3"><label for="password" class="form-label" id="password">密码</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').valueconst 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)alert(error.response.data.message)})})
</script>
</body></html>
提示框
/*** 2.2 封装提示框函数,重复调用,满足提示需求* 功能:* 1. 显示提示框* 2. 不同提示文字msg,和成功绿色失败红色isSuccess(true成功,false失败)* 3. 过2秒后,让提示框自动消失*/const myAlert = document.querySelector( '.alert' )function alertFn(msg, isSuccess) {// 1> 显示提示框myAlert.classList.add('show')// 2> 实现细节myAlert.innerText = msgconst bgStyle = isSuccess ? 'alert-success' : 'alert-danger'myAlert.classList.add(bgStyle)// 3> 过2秒隐藏setTimeout(() => {myAlert.classList.remove('show')// 提示:避免类名冲突,重置背景色myAlert.classList.remove(bgStyle)}, 2000)}
form-serialize 插件
form-serialize 是一个 JavaScript 库,用于将 HTML 表单的数据序列化为字符串或对象1。
你可以使用 form-serialize 来简化获取表单数据的过程。它支持两种输出格式:URL 编码(默认)和哈希(JavaScript 对象)
<!-- 3.1 引入插件 --><script src="./lib/form-serialize.js"></script>```2. 然后修改代码```js// 3.2 使用serialize函数,收集登录表单里用户名和密码const form = document.querySelector('.login-form')const data = serialize(form, { hash: true, empty: true })console.log(data)// {username: 'itheima007', password: '7654321'}const { username, password } = data
完整代码
<!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>11.案例_登录</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="login-form"><div class="mb-3"><label for="username" class="form-label" id="username">账号名</label><input type="text" class="form-control username" name="username"></div><div class="mb-3"><label for="password" class="form-label" id="password">密码</label><input type="password" class="form-control password" name="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="./libs/form-serialize.js"></script>
<script>/*** 2.2 封装提示框函数,重复调用,满足提示需求* 功能:* 1. 显示提示框* 2. 不同提示文字msg,和成功绿色失败红色isSuccess(true成功,false失败)* 3. 过2秒后,让提示框自动消失*/const myAlert = document.querySelector( '.alert' )function alertFn(msg, isSuccess) {// 1> 显示提示框myAlert.classList.add('show')// 2> 实现细节myAlert.innerText = msgconst bgStyle = isSuccess ? 'alert-success' : 'alert-danger'myAlert.classList.add(bgStyle)// 3> 过2秒隐藏setTimeout(() => {myAlert.classList.remove('show')// 提示:避免类名冲突,重置背景色myAlert.classList.remove(bgStyle)}, 2000)}// 目标1:点击登录时,用户名和密码长度判断,并提交数据和服务器通信// 1.1 登录-点击事件document.querySelector('.btn-login').addEventListener('click', () => {const form = document.querySelector('.login-form')const data = serialize(form, { hash: true, empty: true })const { username, password } = data// 1.2 获取用户名和密码// const username = document.querySelector('.username').value// const password = document.querySelector('.password').value// console.log(username, password)// 1.3 判断长度if (username.length < 8) {alertFn('用户名必须大于等于8位',false)console.log('用户名必须大于等于8位')return // 阻止代码继续执行}if (password.length < 6) {alertFn('密码必须大于等于6位',false)console.log('密码必须大于等于6位')return // 阻止代码继续执行}// 1.4 基于axios提交用户名和密码// console.log('提交数据到服务器')axios({url: 'http://hmajax.itheima.net/api/login',method: 'POST',data: {username,password}}).then(result => {alertFn(result.data.message,true)console.log(result)console.log(result.data.message)}).catch(error => {console.log(error)console.log(error.response.data.message)alert(error.response.data.message)})})
</script>
</body></html>