一. 前后端交互流程
1.服务器 : 提供某种服务器的机器(计算机)
qq音乐:音频服务器 , 迅雷:文件服务器 ,
qq邮箱:邮件服务器,爱奇艺:视频服务器,谷歌:web服务器
2. 前端 访问 服务器的四种方式
1. 直接在地址栏输入网址 ,网页会跳转( 全局刷新 )
2. a标签的href属性 ,网页会跳转( 全局刷新 )
3. location.href = 'url' ,网页会跳转( 全局刷新 )
4. AJAX ,网页不会跳转
3. 什么是ajax
1. ajax技术 : 在网页不跳转的情况下 向服务器请求数据
2. ajax应用场景: 局部刷新
4. 前后端交互三个流程
1. 请求 (前端),2.处理 (后端),3.响应(后端)
二. ajax工作原理
1.ajax工作流程
(1) 创建xhr对象:let xhr = new XMLHttpRequest()
(2)设置请求方法和地址 : xhr.open('请求方法','请求地址')
(3)发送请求:xhr.send()
(4)注册响应事件:xhr.onload = function(){}
这个函数不是立即执行的,而是等服务器把数据响应返回才会执行(PS:什么时候执行取决于你的网速快慢)
2. xhr对象的请求状态码
0: 请求未初始化 (open之前)
1: 服务器连接已建立 (open之后)
2: 请求已接收 ( 服务器已经收到你的请求 )
3: 请求处理中 ( 服务器正在处理你的请求 )
4: 请求已完成,且响应已就绪 ( 服务器完成响应, onload事件就是在这里执行 )
3.ajax组成部分
(1)Ajax(阿贾克斯):全称 Asynchronous Javascript And XML(异步的js与xml),说人话: 用js发送异步的网络请求
(2)A : Asynchronous 异步
同步 : 指的是代码按照从上往下顺序执行
异步 : 代码不会立即执行,而是要等一会儿执行
ECMAScript只有两个语法是异步的:定时器 与 ajax
DOM事件也是属于异步的,但是这个是属于DOM的执行机制。所以一般在讨论js同步和异步的 时候,主要以js为主,DOM一般不讨论。
(3)J:Javascript
(4)A :And
(5)X : XML 与 XMLHttpRequest
XML : 解决跨平台数据传输。
在JSON没有出来以前, 网络传输主要以XML格式数据为主。 后来JSON问世,逐渐取代XML。
4.HTTP工作原理(常见面试点)
1. get与post区别
1.传参方式不同:
get请求: 直接在url后面拼接参数 (参数在url中,安全性不高)
get传参格式: url?key=value
post请求:需要设置请求头(固定语法):xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded') (注意:这是固定格式,错一个字母都不行)
使用xhr的send方法发送参数: xhr.send('参数名=参数值'); (注意:不要加前面的?)
2. 数据大小不同:
get有大小限制, 一般 2-5 MB
post没有大小限制 (文件上传)
3. 传输速度不同:
get传输速度快
post传输速度慢
4. 安全性不同:
get安全性低
post安全性高 (登录、注册必须是post请求)
2- onreadystatechange事件
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 )
}
}
2. put与patch区别
全局更新: put
局部更新: patch
3.HTTP原理 : 网络传输协议
1.http网络协议 :规定网络数据传输的格式
2.http组成部分:请求报文 + 响应报文
2.1 浏览器发给服务器的格式:请求报文
2.2 服务器响应给浏览器的格式:响应报文
3.请求报文:
(1)请求行:请求方法和请求地址
(2)请求头:浏览器告诉服务器我发给你的数据是什么格式(普通字符串,Json,文件二进制)
(3)请求体:请求参数
4.响应报文:
(1)响应行:响应状态码
2xx:请求ok
200:请求成功
204:一般出现在post请求,表示数据继续传输
3xx:重定向(服务器主动修改浏览器网址)
302:服务器端重定向
4xx:前端出问题
404:url错误
400:常见于参数错误
403:没有权限(没有登录)
413: 文件超过最大限制
5xx:服务器问题
500:服务器内部错误
(2)响应头:服务器告诉浏览器我发给你的数据是什么格式
(3)响应体:服务器响应的数据
5.ajax工作原理:设置请求报文的过程
4. 网页从输入url到渲染的流程
1. DNS解析 :域名解析成ip
2. TCP三次握手:保证数据传输的 安全 + 可靠
(1)浏览器-->服务器
(2)服务器-->浏览器
(3)浏览器-->服务器
3.HTTP连接:请求,处理,响应
ajax法送请求
服务器处理
服务器响应html格式文件
4.渲染引擎渲染返回的HTML文件
(1)解析HTML:得到DOM树
(2)解析css:得到样式树
(3)渲染树 = dom树+样式树
(4)渲染引擎 开始绘制渲染树,并呈现页面
5.文件上传:
1.前置知识点
1.1 file表单, 默认自带点击事件,作用是选择文件
1.2 上传文件‘必须’要使用原生内置的FormData对象
(1)文件需要设置单独的请求头 : multipart/form-data
(2)文件以二进制方式传输(文本是utf8编码,但是文件不是)
1.3 file表单有一个特殊的事件onchange事件 : 用户选择了文件就会执行
文件上传流程
1.给file表单注册onchange事件 (用户选择了就会执行)
2.获取用户选择的文件
this.files[0]
3.创建FormData对象 (只要是上传文件必须要用FormData)
let fd = new FormData()
4.吧文件添加到FormData对象中
fd.append(‘接口文档参数’,文件对象)
5.使用ajax发送fd对象
FormData对象自动吧你的文件变成二进制。还会自动帮你设置请求头
// 1.给file表单注册onchange事件
document.querySelector('[type="file"]').onchange = function(){
//console.log(this.files) //数组用户选择所有图片
let file= this.files[0] //获取文件数据
const fd = new FormData() //创建FormData对象
fd .append('avatar',file) //添加参数 .append('参数名',参数值)
// 发送axios请求
axios({
url:'http://www.liulongbin.top:3009/api/upload/avatar',
method:'post',
data:fd,
}).then(res=>{
//成功回调
// console.log(res)
if(res.data.code == 200){
document.querySelector('img').src = `http://www.liulongbin.top:3009${res.data.url}`
}
})
}
自定义文件上传按钮思路
第一种:
(1)设置file表单为hidden
(2)给自定义按钮注册点击事件:触发file表单点击
第二种:
(1)label标签的for属性,设置成file表单的id 此时点击label就相当于点击file表单
label的作用是让某个制定的标签被选中
6.函数防抖和节流
防抖:
1.函数防抖 : 单位时间内,频繁触发一个事件, 以'最后一次'触发为准
2.防抖应用场景: 输入框输入事件
3.防抖流程 :
3.1 声明一个全局变量存储定时器ID
3.2 每一次触发交互的时候,先清除上一次定时器。以本次触发为准
3.3 开启本次定时器
流程 :
<body>
<input type="text" placeholder="请输入文本">
<script>
/*
1.函数防抖 : 单位时间内,频繁触发一个事件, 以'最后一次'触发为准
2.防抖应用场景: 输入框输入事件
3.防抖流程 :
3.1 声明一个全局变量存储定时器ID
3.2 每一次触发交互的时候,先清除上一次定时器。以本次触发为准
3.3 开启本次定时器
*/
//声明一个全局变量存储定时器ID
let timeID = null
//输入框输入事件
document.querySelector('input').addEventListener('input', function () {
//先清除之前的定时器
clearTimeout(timeID)
// 开启本次定时器
timeID = setTimeout(() => {
//function函数: this->window
//箭头函数 this->上级this 表单
console.log(`发送ajax,搜索内容是${this.value}`)
}, 500)
})
</script>
</body>
节流:
1.函数节流 : 单位时间内,频繁触发一个事件, 只会触发一次
2.节流场景 : 解决高频事件
鼠标移动 :onmousemove
滚动条事件:onscroll
3.节流实现:
3.1 声明一个全局变量存储触发时间 let lastTime = null
3.2 每一次触发事件,获取当前时间 let currentTime = Date.now()
3.3 判断 当前时间 与 上一次触发时间,是否超过间隔 currentTime-lastTime>=500
3.4 如果超过触发间隔,则执行事件处理代码。 然后存储本次触发事件
流程 :
/*
1.函数节流 : 单位时间内,频繁触发一个事件, 只会触发一次
2.节流场景 : 解决高频事件
鼠标移动 :onmousemove
滚动条事件:onscroll
3.节流实现:
3.1 声明一个全局变量存储触发时间 let lastTime = null
3.2 每一次触发事件,获取当前时间 let currentTime = Date.now()
3.3 判断 当前时间 与 上一次触发时间,是否超过间隔 currentTime-lastTime>=500
3.4 如果超过触发间隔,则执行事件处理代码。 然后存储本次触发事件 lastTime = currentTime
*/
//(1) 声明一个全局变量存储触发时间 let lastTime = null
let lastTime = null
let i = 1
// 页面滚动事件
window.onscroll = function(){
// (2)获取现在的时间
let currentTime = Date.now()
//(3)判断当前时间 - 上一次触发事件 >= 节流间隔
if(currentTime-lastTime>=10000){
console.log(`第${i++}次触发`)
lastTime=currentTime
}
}