Ajax
Ajax
一、回顾 和 目标
重点内容回顾 和 今天的学习目标
回顾:
-
http://ajax-api.itheima.net:80/public/images/0.webp
- 协议:http
- 主机:ajax-api.itheima.net
- 端口:80
- 资源路径:/public/images/0.webp
-
ajax的作用?
- 不刷新页面和 服务器通讯
-
接口
-
文档-->接口文档
- ajax和服务器通讯-->调用接口,调接口
-
ajax调用接口类似于调用后端写的方法
-
-
axios
- 是个什么?
- 请求库,基于
ajax封装
- 请求库,基于
- get请求?
axios.get(url,{params:{key:value}})--->url?key=value&key2=value2
- post请求?
axios.post(url,{key:value})
- 是个什么?
-
ajax开发的核心步骤:
- 请求
- 什么时候发
- 是否需要携带数据
- 发请求之前有什么逻辑
- 响应
- 如何获取数据?then
- 获取到数据之后的逻辑
- 弹框提示用户
- 渲染页面-->
arr-map-->htmlArr-join->htmlString-->innerHTML(appendChild)
- 请求
目标:
- Form表单+ajax
- 几种不同提交数据的格式
二、axios-config模式
除了昨天的
.get,.post,axios也支持传入对象的形式发送请求,咱们来研究一下
概念:
- 通过属性的方式设置请求需要的内容
- 地址
- 方法
- 参数
- ....
步骤:
- 根据文档确认调用方法并测试
get请求+传参- 测试机器人接口
post请求+传参- 测试登录接口
axios-config模式
这一节咱们学习了axios一种新的发请求方法,现在发请求可以用几种不同的写法啦,功能上没啥区别:
-
开发中用哪个?
axios({})-->- 不需要记忆不同的方法
- 只需要记忆配置即可,一个方法即可发送各种不同的请求
- 推荐用法
axios.get/.post
-
选项,配置在哪里查询?是否需要背下来?
- 看官方文档
- 不需要,随用随查即可
需求:
- 打开页面获取所有数据并渲染
- 参考思路:
- 什么时候发请求?
- window.onload
- 是否要携带数据?
- 不需要,获取所有英雄
- 获取到数据之后的逻辑?
- 渲染到页面上
- 输入内容按下回车,检索数据并渲染
- 什么时候发请求?
- keyup, e.keyCode===13
- 是否要携带数据?
- 需要,携带value
- 获取到数据之后的逻辑
- 渲染到页面上
- 什么时候发请求?
- 搞定之后简化代码
三、form表单
form表单-原生提交数据
对于有多个数据需要提交的场景,一般会结合
form表单来完成,原生form表单可以用来提交数据(目前基本不这么用,了解即可),咱们来测试一下
适用场景
form表单常用于网页中需要收集多个数据的位置,比如,登录,注册,信息设置等。。
常见组成:
- 表单元素:
form标签 - 表单输入元素:常见的有
input,textarea,select... - 提交按钮:
button type="submit"- type默认值为submit,可以省略
input type=submit
<form action="http://ajax-api.itheima.net/api/data" method="post">
<input type="text" placeholder="请输入用户名" />
<br />
<input type="text" placeholder="请输入喜欢的食物" />
<br />
<input type="textarea" placeholder="请输入个性签名" />
<br />
<button type="submit">提交</button>
</form>
原生数据提交
form标签设置:action:接口地址method:请求方法
表单输入元素设置:name:提交到服务器数据的key(参数)
- 基于提供的接口测试并验证几个问题:
- 服务器是否获取到了
form表单提交的数据? - 表单输入元素的
name的作用? - 页面重新加载了吗?
- 请求体中确认提交的数据格式
- 服务器是否获取到了
- 测试用接口:传送门
form表单-原生提交数据
原生的form表单如何提交数据,写法上不需要掌握,需要记住如下几点:
-
form表单是否可以提交数据到服务器?- 可以的
-
直接用
form表单提交数据,和用ajax最大的区别是?- 页面会刷新,目前基本不用他
form表单-ajax提交数据
直接用
form表单提交数据带来的用户体验并不好,咱们这一节通过ajax来提交数据
步骤:
- 阻止事件的默认行为(下面两者取其一):
button的点击事件form的submit事件- 目的:避免
form提交数据
axios根据文档设置,地址,方法,参数..- 提交数据
测试:
-
测试2种事件绑定语法
- 表单的
submit事件 button的click事件
- 表单的
-
测试数据提交
form表单-ajax提交数据
如何将表单和ajax结合起来,核心代码就是获取表单中输入元素的value值,并通过ajax提交:
-
ajax提交和form原生提交最大的区别是?
- 页面是否刷新
- ajax不刷新
- form刷新-->目前基本不用
- 页面是否刷新
-
为什么需要阻止
form的submit和button的click事件?-
不阻止,页面会刷新
-
e.preventDefault()->阻止默认行为a默认行为-->跳转e.preventDefault()- a点击不跳转
-
表单默认会提交数据
-
注意:
axios()的属性- 顺序,可以改
- 名字,不能改
axios找不到- 我用的是本地
- 大伙本地如果没有,用在线的
- 表单结构和我不同,获取的语法,不一样的
form表单-form-serialize插件
作用:
form-serialize的作用是简化获取表单数据
使用步骤:
- 导入
form-serialize插件 - 调用
serialize传入form表单和选项,即可获取- 导入之后全局会增加
serialize方法
- 导入之后全局会增加
- 注意: 表单输入元素需要有值,才可以正常获取
serialize(form表单,{hash:true}) // 对象格式
serialize(form表单,{hash:false})// key=value格式
测试:
- 基于上一节的代码调整
- 测试
{hash:true}和{hash:false}的区别 - 使用插件替换数据部分的取值逻辑
form表单-form-serialize插件
这一节咱们学习了一个插件form-serialize,根据传入选项的不同,获取到的数据格式也略有差异:
-
hash属性和获取到数据格式的对应关系- 对象格式
{key:value,key2:value2}-->{hash:true} - 字符串格式
key=value&key2=value2-->不写
- 对象格式
-
form-serialize简化了什么操作?- 表单取值
三、FormData
FormData-基本使用
FormData
概念:
FormData是浏览器提供的内置对象- 以
key/value的形式保存数据 - 能够结合
ajax进行数据提交
常用语法:
- 通过
new关键字实例化 .append(key,value)添加数据.get(key)获取key对应的值- 可以保存文件
// 实例化时传入Form表单 自动获取数据
const data = new FormData(form表单)
// 直接输出看不到数据
console.log(data)
// 通过get方法获取对应的值
console.log(data.get('username'))
console.log(data.get('email'))
console.log(data.get('habbit'))
// 添加键值对
data.append('friend','jack')
console.log(data.get('friend')) // jack
FormData-基本使用
FormData的基本语法,它可以用来保存数据,也可以结合ajax进行数据提交(目前还没结合ajax)
-
使用
FormData是否需要导入其他.js文件?- 不需要,是内置对象
-
FormData的实例化对象通过哪个方法添加数据?append(name,value)
-
FormData的实例化对象如何获取添加的数据?.get(name)
FormData-type=file语法补充
浏览器中可以使用文本域让用户选择文件,如果要结合
FormData使用需要补充一些语法,咱们一起来看看
语法:
accept属性引导用户选择文件- 多个用
,分隔 image/*,所有图片- 只是给用户引导,引导,引导
- 多个用
onchange会在选择的文件改变时触发files属性可以获取选择的文件
<body>
<input type="file" name="avatar" accept="image/*" placeholder="请选择头像">
<script>
document.querySelector('input').onchange = function(e){
console.log('文件信息', e.target.files[0])
}
</script>
</body>
FormData-文本域语法补充
-
accept属性是否可以限制用户选择的文件?- 不能限制,只是推荐
-
onchange会在什么时候触发?- 内容改变-->选了一个不同的文件
-
files属性是什么类型?-
伪数组
- key是数字,0,1,2,...
- 有length属性
-
document.querySelectorAll()--->伪数组
-
FormData-头像上传接口
结合刚刚学习的语法,咱们来调用一下头像上传接口
需求:
- 测试头像上传接口
- 获取上传之后的图片地址
- 设置给
img标签
模板:
- 实例化
FormData - 通过
append方法添加数据(文件) - 结合
axios的data提交
<h2>直接通过FormData</h2>
<input type="file" accept="image/*" >
<img src="" alt="" />
<button>上传</button>
FormData-头像上传接口
结合头像接口+FormData实现了头像上传,重点是演示如何调用这个接口,有如下需要掌握的点:
-
FormData的append方法中的key根据什么来设置?- 根据接口文档设置
-
FormData结合axios提交,设置在哪个属性?data- 请求体中的数据,都是通过
data来提交
小节回顾
重点内容有哪些呢?
-
Form表单
- 默认表单提交数据页面会刷新
- 现在基本不用
-
Form表单+ajax
-
form表单的onsubmit事件
-
button type=submit按钮的点击事件
-
两者选择一个,阻止默认行为
e.preventDefault() -
axios({ url:"", method:"", data:{ username:document.querySelector("元素").value, food:document.querySelector("元素").value //... } })
-
-
form-serialize- 快速的获取表单元素中输入元素的value值
serialize(form表单)-->key=value&key2=value2的格式serialize(form表单,{hash:true})-->{key:value,key2:value2}
-
FormData+input type=file+axios 头像上传
demo-头像上传
需求:
- 正常上传,替换默认图片
- 错误上传,提示用户
分析:
<div class="thumb-box">
<!-- 头像 -->
<img src="./images/cover.jpg" class="img-thumbnail thumb" alt="">
<div class="mt-2">
<input type="file" id="iptFile" accept="image/*" style="display: none;">
<!-- 选择头像图片的按钮 -->
<button class="btn btn-primary" id="btnChoose">选择 & 上传图片</button>
</div>
</div>
- 如何点击按钮弹出文件选择框?
- 点击按钮的时候
- 拿到文件选择标签,触发一下它的
click
- 发请求
- 什么时候发?
- input标签的 change事件中
- 携带什么参数?
- new FormData-->append(从文档看,e.target.files[0])
- 什么时候发?
- 接收响应
- 在哪接收响应?
- then
- 接收到响应之后的逻辑?
- 设置
img的src属性
- 设置
- 在哪接收响应?
demo-头像上传
这一节咱们完整实现了头像上传功能,界面也更为精美,有哪一些需要掌握的点呢?
- 如何点击按钮弹出文件选择框?
文件选择框.click()
axios结合哪个对象可以上传文件?FormData
- 上传成功之后如何让
img标签显示上传的图片呢?src属性
四、Content-Type
不同的数据格式
不同接口对于提交数据格式的要求略有不同,咱们结合接口文档的要求,看看
axios如何提交这三种格式的数据
概念:
axios是一个网络请求库,内部有很多的逻辑- 对于接口对于数据格式的要求,开发者只需要传递对应格式的数据即可
- 其余的事情
axios会帮我们做
测试
- 基于模板进行测试
- 通过如下3个接口确认body的格式
axios在请求体中传递的数据通过data属性设置- 在
network中确认提交数据的原始格式
<!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>Document</title>
</head>
<body>
<h2>form-data</h2>
<input class="ipt" type="file" accept="image/*" />
<h2>application/json</h2>
<button class="json">测试登录接口</button>
<h2>urlencoded</h2>
<button class="urlencoded">测试urlencoded格式</button>
<script src="./lib/axios.js"></script>
<script>
// 1.测试formData
document.querySelector('.ipt').onchange = function (e) {
// 调用头像上传接口 提交图片
const data = new FormData()
data.append('avatar', e.target.files[0])
axios({
url: 'http://ajax-api.itheima.net/api/file',
method: 'post',
data: data,
}).then(res => {
console.log('res:', res)
})
}
// 2.测试application/json
document.querySelector('.json').onclick = function () {
axios
.post('http://ajax-api.itheima.net/api/login', {
username: 'admin',
password: '123456',
})
.then(res => {
console.log('res:', res)
})
}
// 3.测试 application/x-www-form-urlencoded
document.querySelector('.urlencoded').onclick = function () {
axios({
url: 'http://ajax-api.itheima.net/api/data',
method: 'post',
data: 'name=jack&age=18&friend=rose',
}).then(res => {
console.log('res:', res)
})
}
</script>
</body>
</html>
不同的数据格式
这一节咱们测试了对于body格式要求不同的接口如何传递数据,由于用的是axios,我们只需要更改数据的格式即可
-
本节演示的三种数据格式都是通过
axios()方法中的哪个属性提交?data
-
multipart/form-data:提交什么格式?new FormData()
-
application/json:提交的数据格式?- 写成对象-->
axios会帮我们转为JSON
- 写成对象-->
-
application/x-www-form-urlencoded:提交的数据格式?key=value&key2=value2
content-type的作用
上一节对比了几种对提交格式要求不同的接口如何调用,咱们只需要更改提交的内容格式即可,
axios还帮咱们改了content-type,通过修改这个的值,告诉服务器提交的数据是什么格式
概念:
- 在响应中
Content-Type告诉客户端实际返回的内容的内容类型(浏览器根据这个判断如何解析) - 在请求中,
Content-type客户端告诉服务器实际发送的数据类型
查看方式:
f12打开开发者界面- 切换到
network - 点击请求即可查看
请求中Content-type对比
| 属性值 | 应用场景 |
|---|---|
| application/x-www-form-urlencoded | 表单中不包含文件上传的场景,适用于普通数据的提交(现在很少用) |
| multipart/form-data | 表单中包含上传文件的场景 |
| application/json | 上传json格式数据(文本类) |
- 注意:不同的数据对应不同的请求类型,axios 默认帮我们做了设置处理
content-type的作用
这一节咱们通过请求报文确认了不同body格式,axios帮我们做的特殊处理,改了content-type
-
请求头中的
content-type的作用是?- 告诉 服务器, 提交的内容 是什么格式
-
使用
axios提交不同格式的数据时,content-type是否需要开发者设置?- 不需要,自动的设置
-
我们需要注意什么?
- 文档中明确告诉我们提交的数据格式是什么之后
- 能够根据文档提交不同的数据格式即可
五、图书管理
图书管理-准备工作
今天的最后来完成图书管理这个综合案例,巩固今天所学的内容,来明确一下需求,和文件的结构是什么样?
需求:
- 渲染数据列表
- 新增
- 删除
- 编辑(修改)
文件结构:
图书管理-准备工作 重点内容
-
项目中用到的UI库是?
bootstrap
-
项目中请求库是?
axios
-
项目中通过什么库简化表单数据获取?
form-serialize
axios-基地址
项目中的接口一般开头部分是一样的,可以通过
axios的基地址来统一设置,咱们来看看如何设置,并测试具体的效果
语法:
- 设置基地址之后
- 请求的地址变为:基地址+url地址
// 设置一个
axios.defaults.baseURL='基地址'
测试:
- 测试设置了基地址之后如何发请求
axios-基地址
这一节咱们演示了如何设置基地址,可以通过它简化编码
- 设置基地址之后,后续的请求地址只需要写什么?
- 后面不同的部分
- 基地址适用场景?
- 项目中用的多
图书管理-列表渲染
首先完成列表渲染功能
需求:
- 打开页面时,获取列表数据并渲染到页面上
分析:
-
通过接口测试工具测试接口是否可用?
-
设置基地址
axios.defaults.baseURL
-
请求
- window.onload
- axios
- window.onload
-
响应
- .then
- arr->htmlarr->html->innerHTML
- .then
图书管理-列表渲染
这一节完成了列表渲染,虽然渲染的结构和之前的列表略有不同,套路是类似的,重点在接收到响应的渲染逻辑
- 接收到响应之后的逻辑
bootstrap-modal
新增和编辑都用到了
bootstrap的弹框,咱们来看看如何使用它
概念:
bootstrap提供了modal组件,简化弹框使用
用法1-基于属性:
- 通过文档确认并测试
用法2-基于js
- 通过文档确认并测试
// Modal 参数 弹框的dom对象
const myModal = new bootstrap.Modal(document.querySelector('#box'))
console.log('myModal:', myModal)
// 弹出弹框
myModal.show()
// 等3秒关闭
setTimeout(() => {
myModal.hide()
}, 3000)
模板:
<!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>Document</title>
<!-- 引入 bootstrap 样式表 -->
<link rel="stylesheet" href="./css/bootstrap.min.css" />
</head>
<body>
<button>测试bootstrap的弹框</button>
<!-- bootstrap的js -->
<script src="./lib/bootstrap.min.js"></script>
</body>
</html>
bootstrap-modal
这一节演示了bootstrap中modal组件的使用,并且演示了两种用法
- 是否需要背下来具体的代码?
- 不需要,随用随查
- 属性控制的适用场景?
- 没有逻辑,就是希望 显示/隐藏的时候可以通过属性空
- js控制的适用场景?
- 有逻辑,不仅要显示/隐藏,还要执行其他的逻辑
图书管理-新增
接下来完成新增功能
需求:
- 点击新增弹出新增框
- 输入内容并点击提交时新增内容
- 新增完毕之后更新页面,清空表单
分析:
-
点击弹框
-
请求
-
什么时候发请求?
- 点击确认
onclick
- 点击确认
-
是否需要提交数据?
- 通过插件获取数据+提交
-
-
响应
-
在哪里获取响应?
.then
-
如何判断成功失败?
-
成功之后:关闭弹框,清空表单,更新页面
// 通过表单元素的reset方法实现清空 const addForm = document.querySelector('#addForm') addForm.reset() -
-
获取列表数据的逻辑上一步已经完成,抽取一下?
代码解析
图书管理-新增
这一节咱们完成了图书的新增逻辑,因为涉及到表单提交,清空,所以逻辑较多,但是核心还是围绕着请求和响应,有几个需要注意的地方
- 新增成功之后为什么需要重新通过接口获取数据?
- 新增--->服务器的数据变了
- 本地-->并没有
- 重新调用接口--->问服务器要数据
图书管理-删除
完成删除功能
需求:
- 点击删除(可以提示用户)
- 根据id删除图书(服务器)
- 删除成功更新页面
分析:
-
通过接口测试工具测试接口是否可用?
- 可以用
-
请求:
-
什么时候发请求?
-
点击删除
-
事件委托绑定
-
删除按钮是动态生成的
-
绑定给始终存在的祖先元素(
tbody)
-
-
-
是否需要提交数据?
-
传递
id -
保存自定义属性
-
存:
data-book="xx" -
取:
dataset.book
-
-
-
-
响应:
-
在哪里获取响应?
- then
-
如何判断成功失败?
- 请求成功/失败
-
成功之后:更新页面
- 调用方法
-
图书管理-删除
这一节咱们完成了删除,依旧是围绕着请求和响应来完成的,有这么几个需要注意的细节哦
-
动态创建的元素如何绑定事件?
- 事件委托-->绑给它的祖先
-
data-xxx和dataset的作用?- 保存数据:
data-id='123' - 获取保存的数据:
dataset.id
- 保存数据:
-
删除图书删除的是保存在哪里的图书数据?
- 服务器,删除之后要更新页面
图书管理-编辑状态
接下来完成进入编辑的逻辑
需求:
- 点击编辑,获取对应图书详情
- 弹出编辑框,填充对应的图书数据(包括
id)
分析:
-
请求:
-
什么时候发请求?
- 点击编辑
- 事件委托
-
是否需要携带数据?
-
-
响应:
-
如何弹出编辑框?
const modal =new boostrap.Modal(弹框)modal.show() /modal.hide()
-
编辑框中要保存什么数据?
- 当前点击的数据
-
图书管理-编辑状态
这一节咱们完成了图书编辑前半部分的逻辑,进入编辑状态,依旧围绕着请求和响应来完成,需要注意的点和新增有点类似:
-
动态创建的
dom元素的如何绑定事件?- 事件委托
-
为什么需要通过接口来获取图书的详情?
- 有可能拿行内的数据和服务器的数据不一致
- 直接问服务器要 最准确
图书管理-保存修改
最后来完成保存修改功能
需求:
- 点击确认按钮更新图书数据
- 更新完毕之后,关闭弹框,更新列表数据
分析:
-
请求:
-
什么时候发请求?
- 点击确认 onclick
-
是否需要携带数据?
- form-->插件来生成
-
如何快速的获取数据?
- 插件来生成
-
-
响应:
-
接收到响应之后:关闭弹框,更新列表
hide(),getBooks()
-
是否需要清空弹框中的内容?
-
不需要
-
因为点击编辑内部一定是有数据的
-
-
图书管理-保存修改
最后咱们完成了图书管理-保存修改的逻辑,核心依旧是请求和响应,但是编辑不同于新增,需要明确编辑的元素,这里通过传递id来完成:
-
图书的id保存的位置为什么要隐藏起来?
- 不让用户修改
-
图书管理案例中的图书数据保存在哪里?
- 服务器-->更新数据

浙公网安备 33010602011771号