目录
1.AJAX 概念和 axios 使用
2.认识 URL
3.URL 查询参数
4.常用请求方法和数据提交
5.HTTP协议-报文
5.1 HTTP 协议-请求报文
5.2 HTTP 协议-响应报文
6.接口文档
7.案例 - 用户登录
8.form-serialize 插件
1.AJAX 概念和 axios 使用
“Ajax” 是 “Asynchronous(异步) JavaScript and XML” 的缩写,是一种用于创建动态网页的技术。它允许网页在不重新加载整个页面的情况下与服务器进行交互和更新内容,从而提高用户体验和页面的响应速度。
Ajax 的基本工作流程是:
- 用户在网页上触发事件(如点击按钮)。
- JavaScript 代码使用
XMLHttpRequest
对象向服务器发送请求。 - 服务器处理请求并返回数据。
- JavaScript 代码处理返回的数据,并更新页面内容,而无需重新加载整个页面。
怎么用 AJAX ?
1. 先使用 axios [æk‘sio ʊ s] 库, 与服务器进行 数据通信
- 基于 XMLHttpRequest 封装、代码简单、月下载量在 14 亿次
- Vue、React 项目中都会用到 axios
2. 再学习 XMLHttpRequest 对象的使用,了解 AJAX 底层原理
语法:
1. 引入 axios.js: https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js
2. 使用 axios 函数
- ✓ 传入配置对象
- ✓ 再用 .then 回调函数接收结果,并做后续处理
练习:
需求:请求目标资源地址,拿到省份列表数据,显示到页面
目标资源地址: http://hmajax.itheima.net/api/province
代码:
javascript"><body><p></p><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script>/* 通过后台数据渲染到页面 */const p = document.querySelector('p')axios({url: 'https://hmajax.itheima.net/api/province'}).then(result => {// console.log(result)// console.log(result.data.list)p.innerHTML = result.data.list.join('<br>')})</script>
</body>
2.认识 URL
URL,即统一资源定位符(Uniform Resource Locator),是用来指定互联网资源位置的地址。
一个典型的 URL 由以下几个部分组成:
- 协议(Protocol):指定使用的网络协议,例如
http
、https
、ftp
等。比如https://
表示使用安全的 HTTP 协议。 - 域名(Domain Name):表示资源所在的服务器的名称,例如
www.example.com
。 - 端口号(Port)(可选):指定服务器上用于通信的端口。例如,
http://example.com:8080
指的是端口号为 8080 的服务器。 - 资源路径(Path):指向服务器上特定的资源或文件的位置。例如
/path/to/resource
。 - 查询字符串(Query String)(可选):提供附加的参数或数据,通常以
?
开始。例如?key1=value1&key2=value2
。 - 锚点(Fragment)(可选):指向页面内部的某个部分或位置,通常以
#
开始。例如#section1
。
一个完整的 URL 可能如下所示:
https://www.example.com:8080/path/to/resource?key1=value1&key2=value2#section1
最常见的URL是这样的:
参数说明:
- http 协议:超文本传输协议,规定浏览器和服务器之间传输数据的格式
- 域名:标记服务器在互联网中方位
- 资源路径:标记资源在服务器下的具体位置
3.URL 查询参数
定义:浏览器提供给服务器的 额外信息 ,让服务器返回浏览器想要的数据
语法:http://xxxx.com/xxx/xxx ? 参数名1=值1 & 参数名2=值2
语法:使用 axios 提供的 params 选项
注意:axios 在运行时把参数名和值,会拼接到 url ?参数名=值
城市列表: http://hmajax.itheima.net/api/city?pname=河北省
案例:
地区查询
需求:根据输入的省份名字和城市名字,查询地区并渲染列表
效果图:
代码:
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script>/*获取地区列表: http://hmajax.itheima.net/api/area查询参数:pname: 省份或直辖市名字cname: 城市名字*/const btn = document.querySelector('.sel-btn')btn.addEventListener('click', function () {// 获取表单数据pName = document.querySelector('.province').valuecName = document.querySelector('.city').value// console.log(11)// console.log(cname)axios({url: 'https://hmajax.itheima.net/api/area',params: {pname: pName,cname: cName}}).then(result => {// console.log(result.data.list)document.querySelector('.list-group').innerHTML = result.data.list.map(item => {return `<li class="list-group-item">${item}</li>`}).join('')})})</script>
4.常用请求方法和数据提交
请求方法:对服务器 资源 ,要执行的 操作
使用场景: 当数据需要在服务器上 保存
案例:
数据提交-注册账号
需求:通过 axios 提交用户名和密码,完成注册功能
注册用户 URL 地址: http://hmajax.itheima.net/api/register
请求方法: POST
参数名:
username 用户名(中英文和数字组成,最少 8 位)
password 密码(最少 6 位)
代码:
javascript"><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提交用户和密码, 完成注册*/const btn = document.querySelector('.btn')btn.addEventListener('click', function () {axios({url: 'http://hmajax.itheima.net/api/register',method: 'POST',data: {username: 'linhanxin',password: '123456'}}).then(result => {console.log(result)//获取错误信息,显示给用户看}).catch(error => {alert(error.response.data.message)})})</script>
</body>
axios错误处理,可以让客户端更直观看到错误信息。从而去修改。
捕捉到的 error 是一个错误对象。
5.HTTP协议-报文
5.1 HTTP 协议-请求报文
HTTP 协议:规定了浏览器发送及服务器返回内容的 格式
请求报文 :浏览器按照 HTTP 协议要求的 格式 ,发送给服务器的 内容
请求报文的组成部分有:
- 1. 请求行:请求方法,URL,协议
- 2. 请求头:以键值对的格式携带的附加信息,比如:Content-Type
- 3. 空行:分隔请求头,空行之后的是发送给服务器的资源
- 4. 请求体:发送的资源
5.2 HTTP 协议-响应报文
HTTP 协议:规定了浏览器发送及服务器返回内容的 格式
响应报文 :服务器按照 HTTP 协议要求的 格式 , 返回给浏览器的 内容
响应报文的组成部分有:
- 1. 响应行(状态行):协议、HTTP 响应状态码、状态信息
- 2. 响应头:以键值对的格式携带的附加信息,比如:Content-Type
- 3. 空行:分隔响应头,空行之后的是服务器返回的资源
- 4. 响应体:返回的资源
HTTP 响应状态码
HTTP 响应状态码:用来表明请求 是否成功 完成
比如: 404(服务器找不到资源)
6.接口文档
接口文档 : 描述 接口 的文章 (后端工程师)
接口 :使用 AJAX 和服务器通讯时, 使用的 URL , 请求方法 , 以及参数
传送门 :https://apifox.com/apidoc/shared-1b0dd84f-faa8-435d-b355-5a8a329e34a8
通过接口文档,就可以根据里面的需求来实现代码。
7.案例 - 用户登录
案例-用户登录
- 1. 点击登录时,判断用户名和密码长度
- 2. 提交数据和服务器通信
- 3. 提示信息
- 并且实现成功或者失败返回不同颜色的提示框
代码:
<!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">账号名</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:点击登录时,用户名和密码长度判断,并提交数据和服务器通信// 不要盲目写代码,先写需求,然后再翻译成代码const btn = document.querySelector('.btn-login')const admin = document.querySelector('.alert')btn.addEventListener('click', () => {const username = document.querySelector('.username').valueconst password = document.querySelector('.password').value// 封装函数,提示用户登录状态function status(mes, flag) {// 1.显示提示框admin.classList.add('show')// 2.实现细节admin.innerHTML = mesconst bgStyle = flag ? 'alert-success' : 'alert-danger'admin.classList.add(bgStyle)// 3.提示两秒后消失timeOut = setTimeout(function () {admin.classList.remove('show')admin.classList.remove(bgStyle)}, 2000)}if (username.length < 8) {console.log('账户不能少于8位')status('账户不能少于8位', false)// 不满足条件就返回,不要往下执行return}if (password.length < 6) {console.log('密码不能少于6位')status('密码不能少于6位', false)// 不满足条件就返回,不要往下执行return}// console.log(11)axios({url: 'http://hmajax.itheima.net/api/login',method: 'POST',// 属性名和属性值的变量名一样可以简写data: {username,password}}).then(result => {// 打印对象console.log(result.data.message)status(result.data.message, true)}).catch(error => {// 捕捉错误信息console.log(error.response.data.message)status(error.response.data.message, false)})})</script>
</body></html>
8.form-serialize 插件
作用: 快速 收集表单元素的值
使用:
- 1.引入form-serialize 插件的 js文件
- 2.通过调用serialize(表单,对象)函数来实现
- 使用serialize函数,快速收集表单元素的值
* 参数1:要获取哪个表单的数据
* 表单元素设置name属性,值会作为对象的属性名
* 参数2:配置对象
* hash 设置获取数据结构
* - true:JS对象(推荐)一般请求体里提交给服务器
* - false: 查询字符串(username="Xxx" & )
* empty 设置是否获取空值
* - true: 获取空值(推荐)数据结构和标签结构一致
* - false:不获取空值
- 使用serialize函数,快速收集表单元素的值
代码演示:
<body><form action="javascript:;" class="example-form"><input type="text" name="uname"><br><input type="text" name="pwd"><br><input type="button" class="btn" value="提交"></form><!-- 目标:在点击提交时,使用form-serialize插件,快速收集表单元素值--><!-- 引入插件的js --><script src="./lib/form-serialize.js"></script><script>document.querySelector('.btn').addEventListener('click', () => {// 获取表单对象const form = document.querySelector('.example-form')/*** 2. 使用serialize函数,快速收集表单元素的值* 参数1:要获取哪个表单的数据* 表单元素设置name属性,值会作为对象的属性名* 建议name属性的值,最好和接口文档参数名一致* 参数2:配置对象* hash 设置获取数据结构* - true:JS对象(推荐)一般请求体里提交给服务器* - false: 查询字符串(username="Xxx" & )* empty 设置是否获取空值* - true: 获取空值(推荐)数据结构和标签结构一致* - false:不获取空值*/const data = serialize(form, { hash: true, empty: true })console.log(data)})</script>
</body>
案例-用户登录
使用 form-serialize 插件, 收集 用户名和密码
代码实现:
<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">账号名</label><input type="text" class="form-control username" name="username"></div><div class="mb-3"><label for="password" class="form-label">密码</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="./lib/form-serialize.js"></script><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script>// 目标1:点击登录时,用户名和密码长度判断,并提交数据和服务器通信// 目标2:使用提示框,反馈提示消息// 目标3:使用form-serialize插件,收集用户名和密码// 2.1 获取提示框const myAlert = document.querySelector('.alert')/**2.2 封装提示框函数,重复调用,满足提示需求* 功能:* 1. 显示提示框* 2. 不同提示文字msg,和成功绿色失败红色isSuccess(true成功,false失败)* 3. 过2秒后,让提示框自动消失*/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 登录-点击事件document.querySelector('.btn-login').addEventListener('click', () => {// 1.2 获取用户名和密码// 获取表单对象const form = document.querySelector('.login-form')// 利用serialize插件来实现获取表单的值const data = serialize(form, { hash: true, empty: true })// 利用解构简化开发const { username, password } = dataconsole.log(data)// 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 => {alertFn(error.response.data.message, false)console.log(error)console.log(error.response.data.message)})})</script>
</body>