jQuery:
文档:
https://www.jquery123.com/
https://jquery.cuishifeng.cn/
什么是jQuery:
jquery一个高效的,精简的且功能丰富的JavaScript工具库,满足了各种浏览器的兼容问题
web应用发展的过程中,jquery起到了不可或缺的推动作用
当下框架流行的时代,jquery不再那么适用
使用jquery感受,简单简洁,链式调用,读写一体
jQuery使用:
下载—— 引入、
引入:
<script src="./js/jquery-3.6.0.min.js"></script>
版本 1.x ie6+ ,2.X IE 9+ ,3.X IE10+
入口:
$(document).ready(function () {
// 写jquery代码
})
简写:
$(function () {
// 入口 开始写jq代码
console.log(123)
})
以上两种写法相当于js中的window.onload = function(){}
区别:
/*
1:执行时机
window.onload必须再网页中所有的内容都加载完毕之后才可执行(包括图片img)
$(document).ready(function () {})页面当中的DOM结构绘制加载完毕即可执行,可能
与dom元素关联的并未完全加载完
2:编写个数
window.onload只能写一个
$(document).ready(function () {})可以编写多个 并且都会执行
3:简化写法
window.onload没有简化写法
$(document).ready(function () {})可以简化为$(function(){})
*/
选择器函数:
$是jQuery的简写
$()构造函数
$()就是jQuery()函数 通常被当作jQuery的 "选择器函数"
()括号中写选择器 用来获取html元素
$()函数的作用 对圆括号中选取的html元素自动循环遍历,然后组装成一个
jQuery对象返回
基本选择器:
.css css样式设置,多个数据用对象写法
// $('*').css('font-size', '20px')
// $('#box').css({ color: 'red', 'background-color': 'yellow' })
// $('div').css('color', 'blue')
// $('.aa').css('background-color', 'red')
属性选择器:
// $('input[type="text"]').css({ border: '1px solid red' })
// $('input[type]').css({ border: '1px solid red' })
// $('input[name^="news"]').css({ border: '1px solid red' })
// $("input[name!='newsletter']").css({ border: '1px solid red' })
// $("input[name$='letter']").css({ border: '1px solid red' })
关系(层级)选择器:
// $('div ul').css({ border: '1px solid red' })
// $('div>ul').css({ border: '1px solid red' })
// $('li.active').css({ border: '1px solid red' })
// $('p,ul').css({ border: '1px solid red' })
新增选择器函数:
过滤选择器:
:first 获取第一个元素
:last 获取最后一个元素
:even 匹配所有索引值为偶数的元素,从 0 开始计数
:odd 匹配所有索引值为奇数的元素,从 0 开始计数
:eq(index) 匹配一个给定索引值的元素
:gt(index) 匹配所有大于给定索引值的元素,不包括自身
:lt(index) 匹配所有小于给定索引值的元素,不包括自身
// $('li:first').css({ border: '1px solid red' })
// $('.myul>li:last').css({ border: '1px solid red' })
// $('.myul>li:even').css({ border: '1px solid red' })
// $('.myul>li:odd').css({ border: '1px solid red' })
// $('.myul>li:eq(1)').css({ border: '1px solid red' })
// $('.myul>li:gt(1)').css({ border: '1px solid red' })
// $('.myul>li:lt(1)').css({ border: '1px solid red' })
选择器的方法:
.children() 取得当前元素下的所有子元素,不包含后代元素,, 参数指定子元素
.siblings() 取得当前元素的兄弟元素,不包含本身 , 参数指定相对兄弟元素
.next() 取得当前选择的所有元素后面各自的紧邻元素, 参数指定紧邻元素
.prev() 取得当前选择的所有元素前面各自的紧邻元素, 参数指定紧邻元素
.nextAll() 取得当前选择的元素后面所有的元素
.prevAll() 取得当前选择的元素前面所有的元素
.nextUntil(ele) 选取当前元素之后到ele之间的元素,第二个参数设置对应的元素
.prevUntil(ele) 选取当前元素之前到ele之间的元素,第二个参数设置对应的元素
.parent() 选取当前元素的唯一父元素的集合
.parents() 选取当前元素全部父元素,不包括根元素
.parentsUntil(ele) 选取当前元素的全部父元素,直到ele
.find(expr|obj|ele) 取得所有匹配的元素,参数必须填写
.each() 遍历对象
// chi ldren和find都是基于父元素查找子元素
// $('li').eq(1).css({ border: '1px solid red' })
// $('.myul').children().css({ border: '1px solid red' })
// $('li.active').siblings().css({ border: '1px solid red' })
// $('li.active').next().css({ border: '1px solid red' })
// $('li.active').prev().css({ border: '1px solid red' })
// $('li.active').nextAll().css({ border: '1px solid red' })
// $('li.active').prevAll().css({ border: '1px solid red' })
// $('.list').nextUntil('.list5').addClass('one')
// 给.list3前面直到.list前的元素加上类 one
// $('.list3').prevUntil('.list').addClass('one')
// $('.myul').find('.active').css({ border: '1px solid red' })
// 遍历祖先节点 parent parents parentUntil
// $('span').parent().addClass('one')
// $('span').parents().addClass('one')
// 查找span的祖先元素 但是不包含body
// $('span').parentsUntil('body').addClass('one')
jQuery对象和js对象:
js对象:
JavaScript通过js相关对象方法获取的对象
var box = document.getElementById('box')
jQuery对象:
通过jQuery包装后产生的对象 jQuery对象
console.log($('#box'))
注意:jQuery对象无法应用Dom对象的任何方法,Dom对象无法应用jquery的任何方法
jQuery对象和js对象转换:
转为js对象:
// var $c = $('#box')
// 第一种 转换为js对象
// var c = $c[0]
// console.log(c)
// 第二种 转换为js对象
// var c = $c.get(0)
// console.log(c)
转为jQuery对象:
var box = document.getElementById('box')
var $cr = $(box)
console.log($cr)
jQuery的Dom操作:
.text() 获取文本
.html() 获取文本和元素
.width() 获取盒子宽度
.height() 获取盒子高度
// console.log($('.mytext').text())
// console.log($('.mytext').html())
// // $('.box').text("<a href='#'>超链接</a>")
// $('.box').html("<a href='#'>超链接</a>")
// console.log($('.mytext').width())
// console.log($('.mytext').height())
// $('.mytext').width(100)
// $('.mytext').height(100)
// console.log($('.mytext').innerWidth()) //width +padding
// console.log($('.mytext').innerHeight()) //height +padding
// console.log($('.mytext').outerHeight()) //width +padding+border
// console.log($('.mytext').outerWidth()) //height +padding+border
属性获取与操作:
console.log($('a').attr('href'))
$('a').attr('href', 'http://www.baidu.com')
class的操作:
addClass 添加类
removeClass 删除类
toggleClass 交换类
hasClass 判断类是否存在
$('.mytext').addClass('one')
$('.mytext').removeClass('one')
$('.mytext').toggleClass('two')
console.log($('.mytext').hasClass('two')) //true
DOM节点操作:
.append() 添加到当前节点子元素之后
.prepend() 添加到当前节点子元素之前
.before() 添加到当前元素之前
.after() 添加到当前元素之后
.remove() 当前节点全部删除
.empty() 删除节点内的元素和文本,但当前节点还保留
// dom节点的操作
// 添加
// $('.mytext').append('<h1>我是h1标签</h1>')
// $('.mytext').prepend('<h1>我是h1标签</h1>')
// $('.mytext').before('<h1>我是h1标签</h1>')
// $('.mytext').after('<h1>我是h1标签</h1>')
$('#btn').click(function () {
// $('.mytext').remove()//当前dom全部删除
$('.mytext').empty() //清空子元素 当前dom还在
})
事件:
常用事件:
// $('#btn').click(function () {
// console.log('click')
// })
// $('#btn').dblclick(function () {
// console.log('dblclick')
// })
// $('#btn').mouseenter(function () {
// console.log('mouseenter')
// })
// $('#btn').mouseleave(function () {
// console.log('mouseleave')
// })
事件绑定和解绑:
bind/unbind:
function fn() {
console.log('fn')
}
function fun() {
console.log('fun')
}
// 绑定
$('#btn2').click(function () {
$('#btn1').bind('click', fn)
$('#btn1').bind('click', fun)
})
// 解绑
$('#btn3').click(function () {
$('#btn1').unbind('click')
})
$('#btn4').click(function () {
$('#btn1').unbind('click', fn)
})
on/off:
function fn() {
console.log('fn')
}
function fun() {
console.log('fun')
}
//绑定
$('#btn2').click(function () {
$('#btn1').on('click', fn)
$('#btn1').on('click', fun)
})
// 解绑
$('#btn3').click(function () {
$('#btn1').off('click')
})
$('#btn4').click(function () {
$('#btn1').off('click', fn)
})
阻止冒泡:
e.stopPropagation() 阻止向父元素继续冒泡
e.stopImmediatePropagation() 阻止向后继续冒泡
function outFn() {
console.log('out click')
}
function outFn1() {
console.log('outFn1')
}
function inFn(e) {
// e.stopPropagation() // 阻止向父元素继续冒泡
e.stopImmediatePropagation() //阻止向后继续冒泡
console.log('inFn')
}
function inFn1() {
console.log('inFn1')
}
$('.out').on('click', outFn)
$('.out').on('click', outFn1)
$('.in').on('click', inFn)
$('.in').on('click', inFn1)
动画:
speed:三种预定速度之一的字符串(“slow”,“normal”, or “fast”)或表示动画时长的毫秒数值(如:1000)
easing:(Optional) 用来指定切换效果,默认是"swing",可用参数"linear"
fn:在动画完成时执行的函数,每个元素执行一次。
.show() 显示隐藏的匹配元素
.hide() 隐藏显示的元素
.toggle() 如果元素是可见的,切换为隐藏的;如果元素是隐藏的,切换为可见的
.slideDown() 通过高度变化(向下增大)来动态地显示所有匹配的元素,在显示完成后可选地触发一个回调函数
.slideUp() 通过高度变化(向上减小)来动态地隐藏所有匹配的元素,在隐藏完成后可选地触发一个回调函数
.slideToggle() 通过高度变化来切换所有匹配元素的可见性,并在切换完成后可选地触发一个回调函数
.fadeIn() 通过不透明度的变化来实现所有匹配元素的淡入效果,并在动画完成后可选地触发一个回调函数
.fadeOut() 通过不透明度的变化来实现所有匹配元素的淡出效果,并在动画完成后可选地触发一个回调函数
.fadeTo() 把所有匹配元素的不透明度以渐进方式调整到指定的不透明度,并在动画完成后可选地触发一个回调函数
$('#btn').click(function () {
// $('.box').show()
// $('.box').show('slow')
// $('.box').show(3000)
$('.box').show(3000, function () {
alert('wo的动画执行完成')
})
})
$('#btn1').click(function () {
// $('.box').hide()
$('.box').hide(3000)
})
$('#btn2').click(function () {
$('.box').toggle(3000)
})
$('#btn3').click(function () {
$('.box').slideDown(3000, function () {
alert('wo的动画执行完成')
})
})
$('#btn4').click(function () {
$('.box').slideUp(3000)
})
$('#btn5').click(function () {
$('.box').slideToggle(3000)
})
$('#btn6').click(function () {
$('.box').fadeIn(3000, function () {
alert('wo的动画执行完成')
})
})
$('#btn7').click(function () {
$('.box').fadeOut(3000)
})
$('#btn8').click(function () {
//speed:三种预定速度之一的字符串("slow","normal", or "fast")或表示动画时长的毫秒数值(如:1000)
//opacity:一个0至1之间表示透明度的数字。
//easing:(Optional) 用来指定切换效果,默认是"swing",可用参数"linear"
//fn:在动画完成时执行的函数,每个元素执行一次。
$('.box').fadeTo(3000, 0.6)
})
其他:
.val() 获取文本内容
.trim() 去除文本两边的空格
Ajax:
浏览器中提供的XMLHttpRequest 用法比较复杂,jQuery对XMLHttpRequest进行封装,提供了一些列Ajax相关的函数,降低了Ajax的使用难度
jQuery中发起Ajax请求常用的三个方法:
- $.get()
- $.post()
- $.ajax()
$.get():
专门用来发起get请求,将服务器上的资源请求到客户端进行使用
$.get(url[,data],callback)
url 参数类型 string 必填 要请求的资源地址
data 参数类型 object 不是必填 请求资源要携带的参数
callback 参数类型 function 不是必填 请求成功的回调函数
不带参数的请求:
$('#btn').on('click', function () {
// $.get 发起不带参数的请求
$.get('http://www.liulongbin.top:3006/api/getbooks', function (res) {
// res就是服务器响应回来的数据
console.log(res)
})
})
带参数的请求:
$('#btn1').on('click', function () {
// $.get 发起带参数的请求
$.get(
'http://www.liulongbin.top:3006/api/getbooks',
{ id: 1, bookname: '西游记' },
function (res) {
console.log(res)
}
)
})
$.post():
专门用来发起post请求,向服务器提交数据
$.post(url[,data],callback)
url 参数类型 string 必填 提交数据的地址
data 参数类型 object 不是必填 要提交的数据
callback 参数类型 function 不是必填 数据提交成功的回调函数
$(function () {
$('#btnPost').on('click', function () {
$.post(
'http://www.liulongbin.top:3006/api/addbook',
{ bookname: 'js编程语法', author: 'hello', publisher: '天津' },
function (res) {
console.log(res)
}
)
})
})
$.ajax():
是一个功能比较综合的函数,允许我们对ajax请求进行更详细的配置
$.ajax({
type:"", //请求的方式 例如 GET或POST
url:"", // 请求的url地址
data:{}, // 请求要携带的数据
success:function(res){} //请求成功之后的回调函数
})
$.ajax()发起get请求:
$.ajax({
type: 'GET',
url: 'http://www.liulongbin.top:3006/api/getbooks',
data: { id: 1 },
success: function (res) {
console.log(res)
},
})
$.ajax()发起post请求:
$(function () {
$('#btn').on('click', function () {
var obj = {
bookname: 'ja编程',
author: 'java',
publisher: '上海图书出版社',
}
$.ajax({
type: 'POST',
url: 'http://www.liulongbin.top:3006/api/addbook',
data: obj,
// success: function (res) {
// console.log(res)
// },
// 对象中的方法可以简写为下面
success(res) {
console.log(res)
},
})
})
})
接口:
使用Ajax请求数据时,请求的url地址,就叫做 数据接口(简称接口),每个接口必须有请求方式
http://www.liulongbin.top:3006/api/addbook 添加图书接口(post请求)
http://www.liulongbin.top:3006/api/getbooks 获取图书列表接口(get请求)
postman:
为了验证接口能否被正常访问,使用接口测试工具,来对数据接口进行检测
好处:接口测试工具能让我们在不写代码的情况下,对接口进行调用和测试
接口文档:
接口文档可以包含很多信息,也可以按需进行精简,但是一个合格的接口文档,应该包含以下6个内容,为接口的调用提供依据
- 接口名称 用来标识各个接口的简单说明 如登录接口
- 接口url 接口的调用地址
- 调用方式 接口的调用方式 如GET 或POST
- 参数格式 接口需要传递的参数 每个参数必须包含 参数名称 参数类型 是否必选 参数说明‘
- 响应格式 接口的返回值的详细描述 ,包含数据名称 数据类型 说明
- 返回示例 通过对象的形式,列举服务器返回数据的结构
form表单的具体使用:
什么是表单:
表单在网页中主要负责数据采集的功能,HTML中的form标签,主要用于采集用户输入的信息,并通过form标签的提交操作,把采集到的信息提交到服务器端进行处理
form表单的属性:
action URL地址(后端提供的,这个url地址专门负责接收表单提交过来的数据) 规定提交表单时,向何处发送表单数据
未指定action属性值的情况下,action的默认值未当前页面的url地址
method get或post 规定以何种方式把表单数据提交到 action url
(get 通过url地址栏传递数据,传递的数量小 不安全
post 通过http协议传递 ,传输的数据量大,安全)
enctype 规定在发送表单数据之前如何对其进行编码
application/x-www-form-urlencoded 在发送前编码所有的字符(默认)
multipart/form-data 不对字符编码,文件上传,使用该值
text/plain 空格转换未 + 加号,但不对特殊字符编码(很少用)
<form action="/login" method="get">
<input type="text" name="email" id="" />
<br />
<input type="password" name="password" />
<br />
<input type="checkbox" name="remember" checked />
<br />
<button type="submit">提交</button>
</form>
表单的组成:
- 表单标签
- 表单域 (文本框,密码框,多行文本框,复选框,单选框,下拉选择框,文件上传)
- 表单按钮
form标签的属性:
form标签用来采集数据,form标签的属性 就是用来规定 如何把采集到的数据发送到服务器
表单的同步提交:
点击submit按钮,触发表单提交的操作,从而使页面跳转到action url的行为,叫做表单的同步提交
缺点
- form表单同步提交后,整个页面发生跳转,跳转到action url指向的地址,用户体验差
- form表单同步提交后,页面之前的状态和数据会丢失
解决
表单只负责采集数据,Ajax负责将数据提交到服务器
Ajax提交表单数据:
监听表单提交事件:
.submit()
<body>
<form action="/login" id="f1">
<input type="text" name="username" />
<br />
<input type="password" name="password" />
<br />
<button type="submit">提交</button>
</form>
</body>
<script>
$(function () {
$('#f1').submit(function () {
alert('监听到表单的提交事件')
})
})
</script>
表单的默认行为:
监听到表单提交事件之后,调用事件对象的event.preventDefault()阻止表单的提交和页面的跳转
$(function () {
$('#f1').submit(function (e) {
alert('监听到表单的提交事件')
// 阻止表单的提交和页面的跳转
e.preventDefault()
})
})
快速获取表单内的数据:
jQuery提供了**serialize()**函数,可以一次性的获取到表单中的所有数据(必须为每个表单元素添加name属性)
$(selector).serialize()
<body>
<form action="/login" id="f1">
<input type="text" name="username" />
<br />
<input type="password" name="password" />
<br />
<button type="submit">提交</button>
</form>
</body>
<script>
$(function () {
$('#f1').submit(function (e) {
// alert('监听到表单的提交事件')
// 阻止表单的提交和页面的跳转
e.preventDefault()
var data = $(this).serialize()
console.log(data) //username=1111&password=2222
})
})
</script>
同源策略:
什么是同源策略:
如果两个页面的协议 (http) ,域名(www.xxx.com) 和端口(80) 都相同,则两个页面具有相同的源
http://www.test.com/index.html
http://www.test.com/outer.html 同源
https://www.test.com/about.html 不同源 协议不同
http://blog.test.com/index.html 不同源 域名不同
http://www.test.com:80/outer.html 同源
同源策略 是浏览器提供的一个安全策略
浏览器规定:A网站的JavaScript 不允许和非同源的 网站c之间 进行资源交互
跨域:
什么是跨域:
同源是两个url的协议,域名,端口一致,反之就是跨域
出现跨域的原因:浏览器的同源策略不允许非同源的url之间进行数据交换
网页 http://www.test.com/index.html
接口: https://www.api.com/index.html
报错出现:Access-Control-Allow-Origin 就是跨域
解决跨域:
两种方案解决跨域: JSONP 和CORS
JSONP:
出现的早,兼容性好,程序员为了解决跨域问题,被迫想出来的一种临时解决方案,缺点:只支持get请求,不支持post请求
浏览器的同源策略限制,网页中无法通过Ajax请求非同源的接口数据,但是script标签不受同源策略的限制,可以通过src属性,请求非同源的js脚本
jsonp的实现原理:就是通过script标签的src属性,请求跨域的数据接口,通过函数调用的形式,接收跨域接口响应回来的数据
callback为响应数据所返回到的函数位置,可在后面直接加参数
和ajax请求没有关系,仅是通过script进行请求
<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></body>
<script>
function abc(data) {
console.log('jsonp请求')
console.log(data)
}
</script>
<!-- 返回的是函数调用 -->
<script src="http://www.liulongbin.top:3006/api/jsonp?callback=abc"></script>
<!-- jsonp和ajax之间没有任何关系 -->
</html>
CORS:
出现的较晚,是W3C标准,属于跨域Ajax请求的根本解决方案,支持GET和POST请求,不兼容低版本的浏览器,写法类似于js的ajax
jQuery中JSONP的实现:
jQuery中的JSONP 通过script标签的src属性,实现跨域数据访问的,jQuery采用的是动态创建和移除script标签的方式,来发起JSONP数据请求
在发起JSONP请求的时候,动态向head中append一个script标签
JSONP请求成功之后,动态从head中移除刚才append进去的script标签
$(function () {
$.ajax({
url: "http://www.liulongbin.top:3006/api/jsonp?name='zs'&age=12",
dataType: 'jsonp',
// 发送到服务器的参数名称,默认值为callback
jsonp: 'callback',
// 自定义回调函数名称 默认值为jQueryxxxx
jsonpCallback: 'abc',
success(res) {
console.log(res)
},
})
})
防抖[重要]:
var timer = null //1-1防抖的timer
$('#ipt').on('keyup', function () {
// 1-3 清除timer
clearTimeout(timer)
//省略其他代码....
// 1-2定义防抖
// 获取搜索列表
timer = setTimeout(function () {
getSuggestList(keywords)
}, 800)
})
缓存搜索的列表:
1、定义全局缓存对象:
var cacheObj= {}
2、将搜索结果存储到缓存对象中:
// 渲染UI结构
function renderSUggestList(res) {
// 如果没有数据需要渲染 直接return
if (res.result.length <= 0) {
return $('.suggest-list').empty().hide()
}
var rows = []
// console.log(res.result)
$.each(res.result, function (i, item) {
// console.log(item[0])
rows.push(`
<div class="suggest-item">${item[0]}</div>`
)
})
$('.suggest-list').empty().append(rows.join('')).show()
// 1获取用户输入的内容 当做键
var k = $('#ipt').val().trim()
// 将数据作为值 进行缓存
cacheObj[k] = res
// console.log(cacheObj)
}
3、优先从缓存中获取搜索列表
$('#ipt').on('keyup', function () {
// 1-3 清除timer
clearTimeout(timer)
// 1获取用户输入的内容
var keywords = $(this).val().trim()
// 2 判断用户输入的内容是否为空
// 清空搜索列表
if (keywords.length <= 0) {
return $('.suggest-list').empty().hide()
}
// console.log(keywords)
// 先判断缓存中是否有数据
if (cacheObj[keywords]) {
return renderSUggestList(cacheObj[keywords])
}
// 1-2定义防抖
// 获取搜索列表
timer = setTimeout(function () {
getSuggestList(keywords)
}, 800)
})
节流[重要]:
节流策略:可以减少一段时间内事件的触发频率
场景:
鼠标连续不断的触发某事件(点击),只在单位时间内触发一次
懒加载时要监听计算滚动条的位置,不必每次滑动都触发,可以降低计算的频率,而不必去浪费CPU资源
高铁卫生间是否被占用,由红绿灯控制,红灯表示被占用,绿灯表示可使用
每个人上厕所都要花费5分钟,五分钟之内,被占用的卫生间无法被其他人使用
上一个人使用完毕后,需要将红的重置为绿灯,表示下一个人可以使用卫生间
下一个人在上卫生间之前,需要先判断灯是否为绿灯,来知晓是否能上卫生间
节流阀为空,可以执行下次操作;不为空,不能执行下次操作
当前操作执行完,必须将节流阀重置为空,表示可以执行下次操作了
每次执行操作前,先判断节流阀是否为空
$(function () {
// 获取图片
var angel = $('#angel')
// 定义一个timer节流阀
var timer = null
$(document).on('mousemove', function (e) {
//每次执行操作前,先判断节流阀是否为空 不为空 不能执行(证明距离上次执行不足16毫秒)
if (timer) {
return
}
timer = setTimeout(function () {
console.log(e.pageX, e.pageY)
angel.css('top', e.pageY + 'px').css('left', e.pageX + 'px')
timer = null //设置了鼠标跟随效果后,清空节流阀 方便下次开启定时器
}, 160)
})
})
防抖和节流的区别:
- 防抖:事件被频繁触发,防抖能保证只有最后一次触发生效,前面N多次的触发都会被忽略
- 节流:事件被频繁触发,节流能够减少事件触发的频率,有选择性的执行一部分事件
HTTP:
HTTP协议简介:
什么是通信:
通信就是信息的传递和交互
通信三要素: 通信的主体,通信的内容,通信的方式
现实生活中的通信:
张三要把自己考上北京大学的好消息写信告诉自己的好朋友李四
通信的主体(张三和李四),通信的内容(考上北京大学),通信的方式(写信)
互联网中的通信:
服务器把北京大学的介绍通过响应的方式发送给客户端
通信的主体(服务器和客户端),通信的内容(北京大学的介绍),通信的方式(响应)
通信协议:
通信协议是指通信的双方完成通信所必须遵守的规则和约定
通信双方采用预定好的格式来发送和接收信息,这种事先约定好的通信格式,就叫做通信协议
现实中的通信:
写信双方必须遵守的规定的规则,信封的填写规则就是一种通信协议
互联网中的通信:
客户端和服务端之间要实现网页内容的传输,通信的双方必须遵守网页内容的传输协议
网页内容又叫做超文本,网页内容的传输协议又叫做超文本传输协议 简称HTTP协议
什么是HTTP协议:
HTTP协议就是超文本传输协议,规定了客户端和服务端之间进行网页内容的传输时,所必须遵守的传输格式
客户端要以HTTP协议要求的格式把数据提交到服务器
服务器要以HTTP协议要求的格式把内容响应给客户端
HTTP协议交互的模型:
HTTP协议采用了请求/响应的交互模型
HTTP请求消息:
由于HTTP协议属于客户端浏览器和服务器之间的通信协议,所以,客户端发起的请求叫做http请求,客户端发送到服务器的消息,叫做http请求消息
http请求消息又叫做http请求报文
HTTP请求消息组成部分:
HTTP请求消息 由 请求行 ,请求头部,空行和请求体 4个部分组成
请求行:
请求行由请求方式,URL和HTTP协议版本3个部分组成,他们之间用空格隔开
请求头部:
请求头部用来描述客户端的基本信息,把客户端相关的信息告知服务器
User-Agent:当前是什么类型的浏览器
Accept: 用来描述客户端能够接收什么类型的返回内容
Accept-Language :客户端期望接收那种人类语言的文本内容
Host: 请求的服务器名字
Connection:客户端和服务端之间的连接方式请求头部由多行 键值对组成,每行的键和值之间用英文的冒号分隔
空行:
请求头字段的后面是一个空行,通知服务器请求头部到此结束
请求消息中的空行,用来分隔请求头和请求体
请求体:
请求体中存放的,是要通过post方式提交到服务器的数据
只有post请求才有请求体,GET请求没有请求体
HTTP响应消息:
响应消息就是服务器响应给客户端的消息内容 ,也叫做响应报文
HTTP响应消息组成部分:
HTTP响应消息由状态行,响应头部,空行,响应体 4个部分组成
状态行:
由http协议版本,状态码,状态码的描述文本 3个部分组成,之间用空格隔开
响应头:
响应头用来描述服务器的基本信息,响应头部由多行 键值对 组成,每行的键和值之间用英文的冒号分隔
空行:
最后一个响应头部字段结束之后,会紧跟一个空行,用来通知客户端响应头部至此结束
响应消息中的空行,用来分隔 响应头和响应体
响应体:
响应体中存放的,是服务器响应给客户端的资源内容
HTTP请求方法:
什么是HTTP请求方法:
HTTP请求方法 属于http协议中的一部分,请求方法的作用,用来表明 要对服务器上的资源执行的操作
最常用的请求方法 GET和POST
HTTP请求方法:
GET 发送请求来获得服务器上的资源(查询)
POST 向服务器提交资源(提交表单或上传文件) 新增
PUT 向服务器提交新的资源,替换服务器对应的旧的资源(修改)
DELETE 请求服务器删除指定的资源(删除)
HTTP响应状态码:
HTTP响应状态码 属于http协议中的一部分,用来标识响应的状态
响应状态码会随着响应消息一起发送至客户端浏览器,浏览器根据服务器返回的响应状态码,就能知道这次http请求的结果是成功还是失败
http状态码由三个十进制数字组成**,第一个十进制数字定义了状态码的类型**,后两个数字用来对状态码进行细分
1xx 信息,服务器收到请求,需要请求者继续执行操作(实际开发中,很少遇到1xx 的状态码)
2xx 成功,操作被成功接收并处理
3xx 重定向,需要进一步操作以完成请求
4xx 客户端错误,url错误,请求包含语法错误无法完成请求
5xx 服务器错误,服务器在处理请求的过程中发生了错误
2xx成功相关的响应状态码:
2xx表示服务器已成功接收到请求并进行处理
200 ok 请求成功,一般用于get和post请求
201 已创建,成功请求并创建了新的资源,用于put和post请求
3xx成功相关的响应状态码:
服务器要求客户端重定向,需要客户端进一步的操作以完成资源的请求
301 永久移动 请求的资源被永久的移动到新的URL,返回信息包括新的URL
302 临时移动 资源只是临时移动,客户端应继续使用原有的URL
304 未修改 所请求的资源未修改,服务器返回该状态,不会返回任何资源
4xx成功相关的响应状态码:
客户端请求有非法内容跟,从而导致这次请求失败
400 语法有错, 请求参数有错误
401 当前请求需要用户验证 (token)
403 服务器已经理解请求,但是拒绝执行它
404 服务器无法根据客户端请求找到资源(路径错误)
408 请求超时,服务器等待客户端发送的请求超时
5xx成功相关的响应状态码:
服务器未能正常处理客户端的请求而出现的意外错误
500 服务器内部错误,无法完成请求
501 服务器不支持该请求方法,无法完成请求(只有GET和HEAD请求方法是要求每个服务器必须支持的,其它请求方法在不支持的服务器上会返回501)
503 由于超载或者系统维护,服务器暂时无法处理客户端的请求
FormData对象:
为了方便表单处理,HTML5新增了一个FormData对象,可以模拟表单操作
FormData是Ajax 2.0对象用以将数据编译成键值对,以便于XMLHttpRequest来发送数据。XMLHttpRequest Level 2提供的一个接口对象,可以使用该对象来模拟和处理表单并方便的进行文件上传操作。
/*
FormData键值对的形式 发送数据 ,主要针对表单元素
*/
// 1 创建FormData对象
var fd = new FormData()
//2 调用append函数,向fd中追加数据
// 添加数据
fd.append('username', 'zs')
fd.append('pwd', '123456')
// console.log(fd)
// 获取数据
console.log(fd.get('username'))
fd.append('k1', 'v1')
// 设置修改数据,如果指定的key不存在则会新增一条,如果存在,就会修改对应的value值
fd.set('k1', '1')
console.log(fd.get('k1'))
// 判断是否存在对应数据
console.log(fd.has('k1')) //true
console.log(fd.has('k3')) //false
// 删除数据 delete key
// fd.delete('k1')
fd.append('k1', 'v3')
console.log(fd.getAll('k1')) //[] ["1","v3"]
发送数据:
// 1创建formdata对象
var fd = new FormData()
// 2 调用append函数 ,向fd中追加数据
fd.append('username', 'ls')
fd.append('pwd', '12345')
// 使用XMLHttpRequest发送数据
// var xhr = new XMLHttpRequest()
// xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata')
// xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
// xhr.send(fd)
// xhr.onreadystatechange = function () {
// if (xhr.readyState === 4 && xhr.status === 200) {
// console.log(JSON.parse(xhr.responseText))
// }
// }
$.ajax({
url: 'http://www.liulongbin.top:3006/api/formdata',
type: 'POST',
data: fd, //上传formData封装的数据
dataType: 'JSON',
processData: false, //jquery不要去处理发送的数据
success(res) {
console.log(res)
},
})
获取表单数据:
// 获取form表单元素
var form = document.querySelector('#form1')
form.addEventListener('submit', function (e) {
// 阻止默认行为
e.preventDefault()
// 创建formData快速获取到form表单中的数据
var fd = new FormData(form)
$.ajax({
url: 'http://www.liulongbin.top:3006/api/formdata',
type: 'POST',
data: fd, //上传formData封装的数据
dataType: 'JSON',
processData: false, //jquery不要去处理发送的数据
success(res) {
console.log(res)
},
})
})
<form id="form1">
<input type="text" name="username" id="" />
<br />
<input type="password" name="pwd" />
<br />
<button type="submit">提交</button>
</form>
上传文件:
XMLHttpRequest对象,不仅可以发送文本信息,还可以上传文件
思路:
1:定义ui结构
2:验证是否选择了文件
3:向FormData中追加数据
4:使用xhr发起上传文件的请求
// 获取文件上传按钮
var btnEle = document.querySelector('#btnUpload')
// 绑定事件
btnEle.addEventListener('click', function () {
// 获取用户选择的文件列表
var files = document.querySelector('#file1').files
console.log(files)
if (files.length <= 0) {
return alert('请选择要上传的文件')
}
var fd = new FormData()
// 用户选择的文件 追加到FormData中
// avatar 请求的参数
fd.append('avatar', files[0])
var xhr = new XMLHttpRequest()
xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar')
xhr.send(fd)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText)
var data = JSON.parse(xhr.responseText)
if (data.status === 200) {
document.querySelector('#img').src =
'http://www.liulongbin.top:3006' + data.url
} else {
alert('图片上传失败')
}
}
}
})
文件上传进度条:
在创建请求对象后监听上传进度事件
// 获取文件上传按钮
var btnEle = document.querySelector('#btnUpload')
// 绑定事件
btnEle.addEventListener('click', function () {
// 获取用户选择的文件列表
var files = document.querySelector('#file1').files
// console.log(files)
if (files.length <= 0) {
return alert('请选择要上传的文件')
}
var fd = new FormData()
// 用户选择的文件 追加到FormData中
// avatar 请求的参数
fd.append('avatar', files[0])
var xhr = new XMLHttpRequest()
// 监听文件上传进度事件
xhr.upload.onprogress = function (e) {
console.log(1)
// 判断所关联的资源是否具有可以计算的长度
if (e.lengthComputable) {
// console.log(1)
// 计算上传的进度, 计算当前上传进度的百分比
// e.loaded 已经接收的字符数
// total 文件的字节
var procentComplete = Math.ceil((e.loaded / e.total) * 100)
// 动态设置进度条
$('#percent')
.attr('style', 'width:' + procentComplete + '%')
.html(procentComplete + '%')
}
}
// 上传完成事件
xhr.upload.onload = function () {
console.log(123)
$('#percent')
.removeClass()
.addClass('progress-bar progress-bar-success')
}
xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar')
xhr.send(fd)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText)
var data = JSON.parse(xhr.responseText)
if (data.status === 200) {
document.querySelector('#img').src =
'http://www.liulongbin.top:3006' + data.url
} else {
alert('图片上传失败')
}
}
}
})
axios:
Axios 是一个基于 promise 的网络请求库,可以用于浏览器和 node.js
封装了ajax
特性:
- 从浏览器创建 XMLHttpRequests
- 从 node.js 创建 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求和响应数据
- 取消请求
- 自动转换JSON数据
- 客户端支持防御XSRF
使用:
- 引入
<script src="./axios.min.js"></script>
- 使用
// axios发起post请求
// bookname=js编程&author=丁鹿学堂学员&publisher=北京出版社
axios({
method: 'post', //请求方式
url: 'http://www.liulongbin.top:3006/api/addbook', //请求的url
data: {
//请求的数据
bookname: 'jq编程',
author: '学员',
publisher: '上海出版社',
},
})
.then((res) => {
//请求成功执行then方法
// res 响应成功返回的内容
console.log(res)
})
.catch((err) => {
console.log(err)
})
Promise:
问题:多层回调函数 相互嵌套 就形成了回调地狱
缺点: 大量冗余代码相互嵌套可读性很差 不易维护,所以用promise对象
setTimeout(()=>{
setTimeout(()=>{
setTimeout(()=>{
},3000)
},2000)
},1000)
如何解决回调地狱:
Es6 新增了promise的概念
1:Promise是一个构造函数
创建一个promise实例,const p = new Promise() new出来的promise实例对象,代表一个异步操作
2:Promise.prototype上包含一个then方法
每次new Promise得到的实例对象 都可以通过原型链的方式访问到then方法
3:then方法用来预先指定成功和失败的回调函数
4:catch方法用来捕获错误的
var p = new Promise()
p.then(成功的回调函数,失败的回调函数)
p.then(()=>{},()=>{})
**注意:**调用then方法,成功的回调函数是必选的,失败的回调函数是可选的
// Promise 构造函数 参数是一个回调函数,回调函数有两个参数resolve reject
// new出来的promise实例对象,代表一个异步操作
// 异步请求成功执行resolve方法 异步请求失败执行reject方法
//promise状态: 等待 pending 成功 fulfilled 失败rejected 状态一旦改变,不能再更改
new Promise((resolve, reject) => {
console.log($)
// 异步请求
$.ajax({
type: 'GET',
url: 'http://www.liulongbin.top:3006/api/getbooks',
success(res) {
// resolve(res)
reject('错误')
},
})
})
.then((res) => {
console.log(res, 'res')
return res.data
})
.then((res1) => {
console.log(res1, 'res1')
return 4
})
.then((res2) => {
console.log(res2)
})
.catch((err) => {
//专门用来捕获错误的
console.log(err, 'catch')
})
all方法:
Promise.all()方法会发起并行的Promise异步操作,等所有的异步操作全部结束后才会执行下一步的then操作
// http://www.liulongbin.top:3006/api/news
// Promise.all()方法会发起**并行**的Promise异步操作,
// 等所有的异步操作全部结束后才会执行下一步的then操作
function fn() {
return axios({
method: 'GET',
url: 'http://www.liulongbin.top:3006/api/news',
})
}
function fn1() {
return axios({
method: 'GET',
url: 'http://www.liulongbin.top:3006/api/getbooks',
})
}
Promise.all([fn(), fn1()])
.then(([res1, res2]) => {
console.log(res1, res2)
})
.catch((err) => {
console.log(err)
})
race:
Promise.race()方法会发起并行的Promise异步操作,只要任何一个异步操作完成,就立即执行下一步的then操作
// Promise.race()方法会发起**并行**的Promise异步操作,只要任何一个异步操作完成,就立即执行下一步的then操作
function fn() {
return axios({
method: 'GET',
url: 'http://www.liulongbin.top:3006/api/news',
})
}
function fn1() {
return axios({
method: 'GET',
url: 'http://www.liulongbin.top:3006/api/getbooks',
})
}
Promise.race([fn(), fn1()])
.then((res) => {
// 只要任何一个异步操作完成,就立即执行下一步的then操作
console.log(res)
})
.catch((err) => {
console.log(err)
})
基于promise封装异步请求:
1:定义方法getPromise
2:方法接收参数请求的数据,请求的url
3:方法的返回值未promise实例对象
function getBookList(data, url) {
return new Promise((resolve, reject) => {
//异步请求
axios({
method: 'GET',
url: url,
params: data,
})
.then((res) => {
resolve(res)
})
.catch((err) => {
reject(err)
})
})
}
getBookList({}, 'http://www.liulongbin.top:3006/api/getbooks')
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
})
async/await:
async/await 是es6引入的新语法,用来简化promise异步操作,在async/await出现之前,我们只能通过then的方法处理promise异步操作
如果在function中使用了await 那么function必须被async修饰
在async方法中,第一个await之前的代码会同步执行,await之后的代码会异步执行
function fn() {
return axios({
method: 'GET',
url: 'http://www.liulongbin.top:3006/api/news',
})
}
function fn1() {
return axios({
method: 'GET',
url: 'http://www.liulongbin.top:3006/api/getbooks',
})
}
// async 说明函数是一个异步操作的函数
// 按照顺序执行异步请求数据
async function getData() {
console.log(2)
// await等待
let res1 = await fn1()
console.log(res1)
let res2 = await fn()
console.log(res2)
console.log(1)
}
getData()
// async -await 用同步的写法 执行异步操作
ction fn1() {
return axios({
method: ‘GET’,
url: ‘http://www.liulongbin.top:3006/api/getbooks’,
})
}
Promise.race([fn(), fn1()])
.then((res) => {
// 只要任何一个异步操作完成,就立即执行下一步的then操作
console.log(res)
})
.catch((err) => {
console.log(err)
})
### 基于promise封装异步请求:
> 1:定义方法getPromise
>
> 2:方法接收参数请求的数据,请求的url
>
> 3:方法的返回值未promise实例对象
```JavaScript
function getBookList(data, url) {
return new Promise((resolve, reject) => {
//异步请求
axios({
method: 'GET',
url: url,
params: data,
})
.then((res) => {
resolve(res)
})
.catch((err) => {
reject(err)
})
})
}
getBookList({}, 'http://www.liulongbin.top:3006/api/getbooks')
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
})
async/await:
async/await 是es6引入的新语法,用来简化promise异步操作,在async/await出现之前,我们只能通过then的方法处理promise异步操作
如果在function中使用了await 那么function必须被async修饰
在async方法中,第一个await之前的代码会同步执行,await之后的代码会异步执行
function fn() {
return axios({
method: 'GET',
url: 'http://www.liulongbin.top:3006/api/news',
})
}
function fn1() {
return axios({
method: 'GET',
url: 'http://www.liulongbin.top:3006/api/getbooks',
})
}
// async 说明函数是一个异步操作的函数
// 按照顺序执行异步请求数据
async function getData() {
console.log(2)
// await等待
let res1 = await fn1()
console.log(res1)
let res2 = await fn()
console.log(res2)
console.log(1)
}
getData()
// async -await 用同步的写法 执行异步操作