一、ajax工作流程
-
get
//get //(1).实例化ajax对象 let xhr = new XMLHttpRequest() //(2).设置请求方法和地址 //get请求的数据直接添加在url的后面 格式是 url?key=value xhr.open('get', '接口url') //(3).发送请求 xhr.send() //(4).注册回调函数 xhr.onload = function () { console.log(xhr.responseText) } -
post
//post //(1).实例化ajax对象 let xhr = new XMLHttpRequest() //(2).设置请求方法和地址 xhr.open('post', '') //(3).设置请求头(post请求才需要设置) xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded') //(4).发送请求 : 参数格式 'key=value' xhr.send('key=value') //(5).注册回调函数 xhr.onload = function () { console.log(xhr.responseText) }
二、axios框架
axios基本语法
<body>
<button class="btn1">基本使用</button>
<button class="btn2">点我发送get请求</button>
<button class="btn3">点我发送post请求</button>
<!-- 导入axios -->
<script src="./axios.js"></script>
<script>
/*
axios语法 :
axios
.get('url')
.then( res=>{ //请求成功 } )
.catch( err=>{ //请求错误} )
.then( ()=>{ //请求完成 } )
*/
//基本使用
document.querySelector(".btn1").onclick = function() {
axios
.get('https://autumnfish.cn/api/joke/list?num=10')
.then(res=>{
// res : 是axios库对响应数据做了一层包装
console.log(res)
// res.data : 才是服务器响应的数据, axios库自动把json转js
console.log( res.data )
})
.catch(err=>{
//网络错误 : (1)url路径写错了 (2)网络错误
console.log(err)
}).then( ()=>{
//本次请求完成,无论成功失败
console.log( '本次请求完成' )
} )
}
//点我发送get请求
document.querySelector(".btn2").onclick = function() {
axios.get('https://autumnfish.cn/api/joke/list',{
params:{ num:10 }
})
.then(res=>{
console.log(res)
})
}
//点我发送post请求
document.querySelector(".btn3").onclick = function() {
axios.post('http://www.liulongbin.top:3009/api/login',{
username:'sfs',
password:'adada'
}).then(res=>{
console.log( res )
})
}
</script>
axios推荐使用方式
<body>
<button class="btn1">基本使用</button>
<button class="btn2">点我发送get请求</button>
<button class="btn3">点我发送post请求</button>
<!-- 导入axios -->
<script src="./axios.js"></script>
<script>
/*
axios语法 :
axios
.get('url')
.then( res=>{ //请求成功 } )
.catch( err=>{ //请求错误} )
.then( ()=>{ //请求完成 } )
axios常用语法 :
axios({
method:'请求方法',
url:'请求路径',
params : { get参数 },
data : { post参数 }
}).then( res=>{} )
*/
//基本使用
document.querySelector(".btn1").onclick = function() {
axios({
method:'get',
url:'https://autumnfish.cn/api/joke/list?num=10'
}).then(res=>{
console.log( res )
})
}
//点我发送get请求
document.querySelector(".btn2").onclick = function() {
axios({
method:'get',
url:'https://autumnfish.cn/api/joke/list',
params:{ num:10 }
}).then(res=>{
console.log(res)
})
}
//点我发送post请求
document.querySelector(".btn3").onclick = function() {
axios({
method:'post',
url:'http://www.liulongbin.top:3009/api/login',
data:{ username:'admin',password:'123456' }
}).then(res=>{
console.log(res)
})
}
</script>
ajax工作原理
/*
1. http协议 : 网络传输协议
* 协议 : 规定网络数据传输格式
2. http协议组成 : 请求报文 + 响应报文
* 浏览器发请求 必须是 : 请求报文
* 服务器响应 必须是 : 响应报文
3. 请求报文 由三部分组成
3.1 请求行 : 请求方法 + 请求地址
3.2 请求头 : 浏览器告诉服务器,我发送给你的数据是什么格式 (文本、json、图片、音视频等等)
3.3 请求体 : 请求参数
4. 响应报文 由三部分组成
4.1 响应行 : 服务器状态码、 服务器地址等
2xx : 请求成功 200:成功
3xx : 重定向 302 服务端重定向(服务器主动修改浏览器网址)
4xx : 前端的问题 404 : url错误 400: 参数错误 403/402 : 没有权限 405:请求方法错误
5xx : 服务器的问题 500 服务器挂了(后台java代码像js一样爆红了)
4.2 响应头 : 服务器告诉浏览器,我响应给你的数据是什么格式 (文本、json、图片、音视频等等)
4.3 响应体 : 服务器响应数据
5.ajax原理 : 发送请求报文过程
* 给服务器发请求,其实发的就是请求报文
*/
//(1).实例化ajax对象
let xhr = new XMLHttpRequest()
//请求未初始化
console.log(xhr.readyState) //0
//(2).设置请求方法和地址(请求行)
xhr.open("post", "http://www.liulongbin.top:3009/api/login")
//服务器连接已建立
console.log(xhr.readyState) //1
//(3).设置请求头(post请求才需要设置)
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
//(4).发送请求 : 参数格式 'key=value'
xhr.send("username=admin&password=123456")
//(5).注册回调函数
xhr.onreadystatechange = function() {
console.log(xhr.readyState) //2 3 4
//当readyState为4,表示响应数据了
if (xhr.readyState == 4) {
console.log(xhr.response)
}
}
网页从输入url到呈现页面过程
/* 网页从输入url到呈现过程
1.DNS解析 : 把域名解析成ip地址
2.TCP连接三次握手 : 建立 安全可靠的传输协议
2.1 什么是TCP : 一种 传输控制协议
2.2 TCP作用 : 保证HTTP网络传输是 安全 + 可靠的 (检测客户端 与 服务器的网卡是不是通的)
2.3 TCP三次握手 :
第一次: 浏览器 -> 服务器 (你能听到我说话吗?,检测浏览器:发送)
第二次: 服务器 -> 浏览器 (我听到了,你能听到我说话吗。 检测浏服务器: 接收 + 发送)
第三次: 浏览器 -> 服务器 (嗯,我听到了. 检测浏览器: 接收)
3.HTTP请求 : 网络传输协议
3.1 浏览器发送请求
3.2 服务器处理请求
3.3 服务器响应请求
4.服务器响应数据之后,渲染引擎开始渲染页面
4.1 解析html生成:dom树
4.2 解析css生成:样式树
4.3 dom树 与 样式树 合并得到 渲染树
4.4 呈现页面
*/
js链式语法
/*
1.链式语法 : 对象可以连续调用方法
axios.get().then().catch()
2.链式语法底层原理 : 在对象的方法中返回自身
*/
let obj = {
name: '张三',
age: 20,
sex: '男'
}
//给对象添加方法
obj.setName = function (str) {
this.name = str
return this
}
obj.setAge = function (num) {
this.age = num
return this
}
obj.setSex = function (str) {
this.sex = str
return this
}
//调用方法
obj
.setName('李四')
.setAge(22)
.setSex('女')
console.log(obj)//{name: '李四', age: 22, sex: '女', setName: ƒ, setAge: ƒ, …}
onreadystatechange事件
/* 学习目标: XMLHttpRequest对象的两个事件 + xhr对象的请求状态
1. onload事件 : 服务器响应之后执行 ( 一次请求,只会执行一次 )
2. onreadystatechange事件 : xhr请求状态变化会执行 ( 一次请求,会执行多次 )
0: 请求未初始化 (open之前)
1: 服务器连接已建立 (open之后)
2: 请求已接收 ( 服务器已经收到你的请求 )
3: 请求处理中 ( 服务器正在处理你的请求 )
4: 请求已完成,且响应已就绪 ( 服务器完成响应, onload事件就是在这里执行 )
*/
//(1).实例化ajax对象
let xhr = new XMLHttpRequest()
//请求未初始化
console.log( xhr.readyState )//0
//(2).设置请求方法和地址(请求行)
xhr.open('post', 'http://www.liulongbin.top:3009/api/login')
//服务器连接已建立
console.log( xhr.readyState )//1
//(3).设置请求头(post请求才需要设置)
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded')
//(4).发送请求 : 参数格式 'key=value'
xhr.send('username=admin&password=123456')
//(5).注册回调函数
xhr.onreadystatechange = function () {
console.log( xhr.readyState )//2 3 4
//当readyState为4,表示响应数据了
if( xhr.readyState == 4 ){
console.log( xhr.response )
}
}
ajax组成部分
/*
Ajax(阿贾克斯) : Asynchronous Javascript And XML (异步js与XML)
* 说人话 : 用js发送异步请求
A : Asynchronous 异步
同步: 按照顺序从上往下依次执行
异步: 不会立即执行,而是过一会儿执行
* ECMAScript只有两个语法是异步 : 定时器 + ajax
* 事件也是异步的,只是事件属于dom语法。 一般讨论同步异步不包含事件。
J : Javascript
A : And
X : XML (与json完全一致,也是解决数据跨平台传输) 与 XMLHttpRequest
* ajax技术诞生的时候,json还没有流行。 那个时候主要使用 XML数据格式 , 但是随着json问 世,xml逐渐被json所取代。但是这个ajax的x代表xml称呼一直保留至今。
*/
//(1).实例化ajax对象
let xhr = new XMLHttpRequest()
//(2).设置请求方法和地址
//get请求的数据直接添加在url的后面 格式是 url?key=value
xhr.open('get', 'http://wthrcdn.etouch.cn/WeatherApi?city=武汉')
//(3).发送请求
xhr.send()
//(4).注册回调函数
xhr.onload = function() {
console.log(xhr.responseText)
}
get和post的区别
传参方式不同
get参数在url后面拼接(请求行)
post参数在请求体中发送
数据大小不同
get有大小限制,一般 2-5MB
post没有大小限制(文件上传)
传输速度不同
get传输速度快
post传输速度慢
安全性不同
get安全性低
post安全性高(登录、注册必须是post请求)
头像上传
<style>
.thumb-box {
text-align: center;
margin-top: 50px;
}
.thumb {
width: 250px;
height: 250px;
object-fit: cover;
border-radius: 50%;
}
</style>
</head>
<body>
<div class="thumb-box">
<!-- 头像 -->
<img src="./images/cover.jpg" class="img-thumbnail thumb" alt="" />
<div class="mt-2">
<!-- 文件选择框 -->
<!-- accept 属性表示可选择的文件类型 -->
<!-- image/* 表示只允许选择图片类型的文件 -->
<input type="file" id="iptFile" accept="image/*" />
<br />
</div>
</div>
>
<script src="./lib/axios.js"></script>
<script>
/*文件上传
1.前置知识点
1.1 file表单, 默认自带点击事件,作用是选择文件
1.2 上传文件‘必须’要使用原生内置的FormData对象
(1)文件需要设置单独的请求头 : multipart/form-data
(2)文件以二进制方式传输(文本是utf8编码,但是文件不是)
1.3 file表单有一个特殊的事件onchange事件 : 用户选择了文件就会执行
2.文件上传流程
2.1 在file表单的onchange事件中获取用户选择的图片
this.files[0]
2.2 创建FormData对象,将图片添加到fd对象中
let fd = new FormData()
fd.append('接口参数',文件数据)
2.3 ajax发送请求 : 参数必须是formdata对象
*/
//1.给file表单注册onchange事件
document.querySelector('#iptFile').onchange = function(){
// console.log( this )//file表单
//2.获取用户选择的文件
/*
this.files : 伪数组,存储所有的选中的文件
this.files[0] : 取出第一个文件
*/
console.log( this.files[0] )
//3.创建FormData对象
let fd = new FormData()
//4. 调用append方法追加文件
fd.append('avatar', this.files[0] )
//5. ajax发送请求
axios({
url:'http://www.liulongbin.top:3009/api/upload/avatar',
method:'post',
/* 将formdata对象作为参数, fd对象会自动帮我们设置请求头,自动处理文件参数 */
data: fd,
}).then(res=>{
//成功回调
console.log(res)
//6.显示上传成功的图片
document.querySelector('img').src = `http://www.liulongbin.top:3009${res.data.url}`
})
}
</script>
</body>
自定义头像上传按钮
<style>
.thumb-box {
text-align: center;
margin-top: 50px;
}
.thumb {
width: 250px;
height: 250px;
object-fit: cover;
border-radius: 50%;
}
</style>
</head>
<body>
<a href="http://www.baidu.com">百度</a>
<div class="thumb-box">
<!-- 头像 -->
<img src="./images/cover.jpg" class="img-thumbnail thumb" alt="" />
<div class="mt-2">
<!-- 文件选择框 -->
<!-- accept 属性表示可选择的文件类型 -->
<!-- image/* 表示只允许选择图片类型的文件 -->
<input type="file" id="iptFile" accept="image/*" style="display: none" />
<br />
<!-- 选择头像图片的按钮 -->
<button class="btn btn-primary" id="btnChoose">
选择 & 上传图片
</button>
</div>
</div>
<!-- label标签有一个独有的for属性, 它的值是 input元素的id
for作用: 让label与input建立关联。 点击了label相当于点击了input
-->
<label for="iptFile">
<img src="./images/icon.png" width="60px" alt="">
</label>
<script src="./lib/axios.js"></script>
<script>
/* 自定义文件上传按钮思路
1. 隐藏file表单 (设置display为none)
2. 给自定义按钮注册点击事件 , 点击注册 file表单'默认'点击事件
触发注册点击事件 : dom元素.onclick()
触发'默认'点击事件 : dom元素.click()
*/
//点击自定义按钮
document.querySelector('#btnChoose').onclick = function () {
//触发file表单点击事件即可
/*
dom对象.onclick() : 只能触发注册的点击事件, 没有注册则无法触发
dom对象.click() : 触发注册 + 触发默认点击事件 ( a标签、form按钮、file表单 )
*/
document.querySelector('#iptFile').click()
}
//1.给file表单注册onchange事件 : 选择文件触发
document.querySelector('#iptFile').onchange = function () {
//2. 获取用户选择的文件 this.files[0]
//3. 创建FormData对象,把文件添加到fd对象
let fd = new FormData()
fd.append('avatar', this.files[0])
//4.发送ajax
axios({
url: 'http://www.liulongbin.top:3009/api/upload/avatar',
method: 'post',
data: fd,
}).then(res => {
//成功回调
console.log(res)
//把服务器给的url显示到img标签 (可选)
document.querySelector('img').src = `http://www.liulongbin.top:3009${res.data.url}`
})
}
</script>
</body>
函数防抖
/*
1.函数防抖 : 单位时间内,频繁触发一个事件, 以'最后一次'触发为准
2.防抖应用场景: 输入框输入事件
3.防抖流程 :
3.1 声明一个全局变量存储定时器ID
3.2 每一次触发交互的时候,先清除上一次定时器。 然后把本次事件处理代码放入定时器中
*/
let timeID = null
//输入框输入事件
document.querySelector('input').oninput = function(){
//1.先清除之前的定时器
clearTimeout(timeID)
//2.开启本次定时器
timeID = setTimeout(()=>{
//function函数: this->window
//箭头函数 this->上级this 表单
console.log(`发送ajax,搜索内容是${this.value}`)
},500)
}
函数节流
/*
1.函数节流 : 单位时间内,频繁触发一个事件, 只会触发一次
2.节流场景 : 解决高频事件 (滚动条事件高频触发)
3.节流实现:
3.1 声明一个全局变量存储触发时间 let lastTime = null
3.2 每一次触发事件,获取当前时间 let currentTime = Date.now()
3.3 判断 当前时间 与 上一次触发时间,是否超过间隔 currentTime-lastTime>=500
3.4 如果超过触发间隔,则执行事件处理代码。 然后存储本次触发事件 lastTime = currentTime
*/
//声明一个全局变量存储触发时间
let lastTime = null
window.onscroll = function(){
//1.每一次触发,先获取本次时间戳
let currentTime = Date.now()
//2.判断当前时间 与 上一次触发时间 是否超过间隔
if( currentTime - lastTime >= 500 ){
console.log( document.documentElement.scrollTop)
//3.存储本次触发时间
lastTime = currentTime
}
}