js
- 109正则表达式
- 118this关键字指向
- 改变this指向
- 120 定义变量ES6
- 121案例 块级作用域
- 122 箭头函数ES6
- 123解构赋值ES6
- 124对象简写ES6
- 125展开运算符ES6
- 126模块化语法Es6
- 127 面向对象
- 128 构建对象的方式
- 129构造函数的注意问题
- 130面对对象的原型prototype
- 131选项卡
- 132 class_Es6
- 133面向对象继承
- 136初识前后端交互
- 137 ajax
- 请求方式
- ajax封装
- 144 ajax前后端交互案例
- 145 回调地狱问题
- 146 Promise基础语法
- 147 Promise封装ajax
- 149 async和await语法
- 151 fetch
- 156 cookie
- jsonp
- 161闭包
109正则表达式
用于校验内容
两种表达方式
- 字面量
var a=/abc/
表示输入内容必须为abc - 内置构造函数
var b=new RegExp("abc")
方法test( )
包含即可,如:aabc1,值为true或false
110基本元字符
包含即可
- \d包含一位数字(0-9),包含一位即可。若为
var=/\d\d/
则必须包含两个数字,一个数字则不行 - \D包含一位非数字
- 不加反斜杠就是指定的字符
- \s包含一位空白(包含空白缩进换行)
- \S包含一位 非空白
- \w包含一位字母,数字,下划线
- \W包含一位非字母,数字,下划线
.
任意内容都可以(但是若只有一位则不包含换行符\n)- \转义字符
111边界符
!!!!!只能修饰一个字符
^
表示开头var reg=/^\d/
表示开头必须为数字$
表示结尾var reg=/\d$/
表示结尾必须为数字^abc$
开头结尾都限制内容为abc^a\dc$
表示开头必须为a,结尾必须为c,中间必须为一位数字
var a = /^a\dc/
console.log(a.test("a123c"))
console.log(a.test("a1c"))
112限定符号
!!!!!只能修饰一个字符
最少最多
*
表示0-多次+
表示1-多次?
包含0-1个都可
{n}
指定包含n个(需为连续)
var a = /\d{3}/
console.log(a.test("123"))
console.log(a.test("1234"))
console.log(a.test("23"))
var a = /\d{3}\w/
console.log(a.test("12a3"))
console.log(a.test("1234"))
console.log(a.test("a123"))
{n,}表示>=n,即最少为多少个
{n,m}表示含有n-m个满足条件的即可
var a = /\d{2,3}/
console.log(a.test("123"))
//true
console.log(a.test("1a2b3c4"))
//false
console.log(a.test("1a23c4"))
//true
console.log(a.test("3"))
//false
113特殊符号
( )
var a = /(ab){2}/
console.log(a.test("ab"))
//false
console.log(a.test("1ababc"))
//true
|
或.
包含任一项即可
var a = /f|2/
console.log(a.test("af11"))
//true
console.log(a.test("234a"))
//true
console.log(a.test("11"))
//false
|
两边的看做整体
var a = /abc|123/
//包含abc或123任一项即可
console.log(a.test("c1"))
//false
console.log(a.test("abc"))
//true
console.log(a.test("123"))
true
[ ]
包含其中一个即可
var a = /[abc]/
console.log(a.test("c"))
//true
console.log(a.test("ac"))
//true
console.log(a.test("f"))
//false
var a = /[abcdef]{2,4}/
console.log(a.test("c"))假
console.log(a.test("ac"))真
console.log(a.test("abcdefg"))假
-
表示:至[a-z]
表示\w
[0-9]
表示\d
[^abc]
中的^表示取反
var a = /[^abcdef]/
console.log(a.test("c"))假
console.log(a.test("g"))真
114捕获exec
获取满足正则表达式的值
var date = "time is 2023-1-19 23:00:00"
var date3 = "time is 2023-01-19 23:00:00"
var reg=/\d{4}-\d{1,2}-\d{1,2}/
var reg2=/\d{4}-\d-\d{1,2}\s\d\d:\d{2}/
var reg3=/\d{4}-\d{2}-\d{1,2}/
var a=reg.exec(date)
var b=reg2.exec(date)
var c=reg3.exec(date3)
console.log(a[0])
console.log(b[0])
console.log(c[0])
var date = "time is 2023-1-19 23:00:00"
var reg=/\d{4}-\d{1,2}-\d{1,2}/
var a=reg.exec(date)
console.log(a[0])
console.log(a[0].split("-"))
//用-分割
console.log(a[0].split("-").join("/"))
只会捕获第一个遇到的
标识符g
通过
g
或i
标识符取消其惰性
var date = "2023-01-19 2023-01-20"
var reg1=/\d{4}-\d{1,2}-\d{1,2}/
var reg2=/\d{4}-\d{1,2}-\d{1,2}/g
var a=reg1.exec(date)
console.log(a[0])
var b=reg1.exec(date)
console.log(b[0])
var c=reg2.exec(date)
console.log(c[0])
var d=reg2.exec(date)
console.log(d[0])
var date = "2023-01-19"
var reg1=/(\d{4})-\d{1,2}-(\d{1,2})/
var a=reg1.exec(date)
console.log(a)
var reg2=/(\d{4})-(\d{1,2})-(\d{1,2})/
var b=reg2.exec(date)
console.log(b)
加小括号可以单独捕获?
标识符i
不限制大小写
115两大特性
- 懒惰——用全局标识符g解决
- 贪婪,即越多越好——用标识符?解决
var date = "ab12345"
var reg=/\d{1,7}/
var reg2=/\d{1,3}/
console.log(reg.exec(date))
console.log(reg2.exec(date))
- 非贪婪模式用?
var date = "ab12345"
var reg=/\d{1,7}?/
var reg2=/\d{2,3}?/
console.log(reg.exec(date))
console.log(reg2.exec(date))
在限定符上组合使用
- *?
- +?
- ??
- {}?
- {n,m}?
正则与字符串方法
- replace
var str = "abcefac"
var newstr=str.replace(/a/g,"1")
var newstr2=str.replace(/a/,"1")
console.log(newstr)
console.log(newstr2)
- search,找不到则值为-1
- match捕获内容
var str = "abcefacab"
console.log(str.match(/(ab)/))
var reg=/(ab)/
console.log(reg.exec(str))
var date="2023-01-19 2023-01-20"
var reg=/(\d{4})-(\d{1,2})-(\d{1,2})/
var b=reg.exec(date)
console.log(b)
console.log(date.match(/(\d{4})-(\d{1,2})-(\d{1,2})/g))
117案例
118this关键字指向
全局中 指向窗口
在对象中
var obj={
name:"lucy",
fn:function(){
console.log("111",this)
//this指向obj
console.log("111",this.name)
}
}
console.log(obj.fn)
console.log(obj.name)
obj.fn()
//调用
定时器
仍是窗口,因为窗口调用定时器
事件绑定
谁调用,指向谁
改变this指向
call,apply
执行函数,并改变this执行函数的第一个参数
区别:call可直接传参数可传多个。apply只能传两个参数,需要以数组的形式包起来传参数。
bind
改变执行函数。?改变指向为函数的第一个参数,不会自动执行,需要手动执行调用
120 定义变量ES6
let与var
区别
- var可变量提升,let必须先定义后使用
- 变量重名时,var后定义的会覆盖。let会报错。
- 块级作用域
- var只有在函数内部定义的才是局部作用域,在if或其他语句中定义的,它的作用域均为全局作用域。
- let作用域只存于大括号中。
let和const变量
- let 和 const 不允许重复声明变量
- let 和 const 声明的变量不会在预解析的时候解析(也就是没有变量提升)
- let 和 const 声明的变量会被所有代码块限制作用范围
区别
- let 声明的时候可以不赋值, const 声明的时候必须赋值
- let 声明的变量的值可以改变, const 声明的变量的值不可以改变
121案例 块级作用域
122 箭头函数ES6
var fn=function(){
console.log("a")
}
var fn2=()=>{
console.log("b")
}
fn()
//a
fn2()
//b
特点:只有一个参数时可以省略(),函数只有一个返回值时,可以省略return。只执行一句话,可以省略{ }。最终可以简化为
var fn=(a)=>a*100
console.log(fn(2))
//200
console.log(fn(3))
//300
简化映射
var list=[1,2,3,4]
var newlist=list.map(function(item){
console.log(`<li>${item}</li>`)
return `<li>${item}</li>`
})
console.log(newlist)
var newlist2=list.map(item=>`<li>${item}</li>`)
console.log(newlist2)
没有arguments
arguments
可以在没有形参的情况下,通过调用传入实参。形成伪数组
var fn=function(){
console.log(arguments)
}
fn(1,2,3,4)
Array.from方法转成真数组
var fn=function(){
console.log(Array.from(arguments))
}
fn(1,2,3,4)
this指向问题
箭头函数this是父级作用域的
<input id="a"></input>
<script>
var a=document.getElementById("a")
a.oninput=function(){
setTimeout(()=>{
console.log(this.value)
},1)
}
</script>
123解构赋值ES6
快速的从对象或者数组中取出成员的一个语法方式
- 可应用于快速赋值
var a=1,b=2
var [b,a]=[a,b]
console.log(a,b)
//输出结果为2 1
- 快速获取多维数组里的值
var arr=[1,2,[3,4,[5]]]
console.log(arr[2][2][0])
//5
var [a,b,[c,d,[e]]]=arr
console.log(e)
//5
console.log(c)
//3
- 简化获取对象里的值的步骤
var obj={
name:"lucy",
age:18
}
console.log(obj.name,obj.age)
var {name,age}=obj
console.log(name,age)
**
- 快速获取对象的值
**
var obj={
allname:{
name:"lucy",
name2:"mike"
},
age:18,
hobby:[1,2,3]
}
console.log(obj.allname,obj.age,obj.hobby)
var {
allname:{
name,
name2
},
//注意allname里的name与name2不可改变
age,
hobby:[c,d,e]
}=obj
console.log(name2,c)
124对象简写ES6
对象和值一样可省略值?
125展开运算符ES6
...
展开数组
和数组中的concat效果同
var arr=[1,2,3]
var arr2=[4,5,6]
console.log(arr.concat(arr2))
var arr3=[...arr,...arr2]
console.log(arr3)
- 用于复制
var arr=[1,2,3]
var arr2=[...arr]
console.log(arr2)
- 用于箭头函数中吧 参数=》实参=》形参
var fn=(...arr)=>{
console.log(arr)
}
fn(1,2,3,4)
var fn2=function(){
console.log(arguments)
}
fn2(5,6,7,8)
用于不知道数组长度时,进行取最大值or最小值
var arr=[91,12,3,45,32,7,88]
var max=Math.max(...arr)
console.log(max)
//输出91
伪数组转换
var fn2 = function () {
console.log(arguments)
}
fn2(5, 6, 7, 8)
var fn2 = function () {
console.log(...arguments)
}
fn2(5, 6, 7, 8)
var fn3 = function () {
var arr=[...arguments]
//外边用[ ]包住
console.log(arr)
}
fn3(5, 6, 7, 8)
可用于查询一堆标签时,用如上方法转换为数组
对象,(重名,下面的会覆盖上面的)
var obj={
name:"lucy",
age:18
}
var obj2={
name:"mike",
age:19,
hobby:"a"
}
var obj3={
...obj,
...obj2
}
console.log(obj3)
126模块化语法Es6
127 面向对象
128 构建对象的方式
调用系统内置的构造函数创建对象
当 构造函数 和 new 关键字连用的时候,就可以为我们创造出一个对象,就可以动态的向对象中添加成员。
var o1 = new Object()
// 得到一个空对象
o1.name = 'Jack'
o1.age = 18
o1.gender = '男'
//动态添加
字面量
var o1 = {
name: 'Jack',
age: 18,
gender: '男'
}
工厂函数的方式创建对象
优点:复用的代码量相对较少
可以通过传参,改变值
function createObj(){
var obj={}
obj.name="lucy",
obj.hobby=[]
return obj
}
var obj1=createObj()
console.log(obj1)
var obj2=createObj()
console.log(obj2)
改进
function createObj(name,a,b,c){
var obj={}
obj.name=name,
obj.hobby=[a,b,c]
return obj
}
var obj1=createObj("lucy",1,2,3)
console.log(obj1)
var obj2=createObj("mike",4,5,6)
console.log(obj2)
自定义构造函数
相较于工厂函数,能够自动创建函数,自动返回
类似于new Object, new Array, new String
function CreateObj(name,age,a,b){
//自动创建
this.name=name
this.age=age
this.hobby=[a,b]
//自动返回
}
var obj1=new CreateObj("lucy",18,1,2)
console.log(obj1)
129构造函数的注意问题
- 首字母大写
- 构造函数不用再写return
- this指向:在创建新对象(实例化)之和才有了指向(原来应该是windo.this?),
130面对对象的原型prototype
-
每一个函数天生自带一个成员,叫做 prototype,是一个对象空间
-
prototype 对象空间可以由函数名来访问
-
重点: 在函数的 prototype 里面存储的内容,不是给函数使用的,是给函数的每一个实例化对象使用的
-
目的:共用内存
<div id="box">
<ul ></ul>
</div>
<script>
var data1={
name:"lucy",
list:['a',"b","c"]
}
function CreateList(name,list){
this.name=name
this.list=list
}
// CreateList.prototype.render=function(){
// var ul=this.querySelector("ul")
// ul.innerHTML=this.list.map(item=>`<li>${item}</li>`).join("")
// }
var obj1=new CreateList(data1.name,data1.list)
console.log(obj1)
function CreateList2(select,data){
this.ele=document.querySelector(select)
this.name=data.name
this.list=data.list
//开始渲染
this.render=function(){
var ul=this.ele.querySelector("ul")
//格式
ul.innerHTML=this.list.map(item=>`<li>${item}</li>`).join("")
console.log(ul)
}
}
var obj2=new CreateList2("#box",data1)
console.log(obj2)
obj2.render()
</script>
原型使用
var data1={
name:"lucy",
list:['a',"b","c"]
}
function CreateList2(select,data){
this.ele=document.querySelector(select)
this.name=data.name
this.list=data.list
//开始渲染
// this.render=function(){
// }
}
CreateList2.prototype.render=function(){
var ul=this.ele.querySelector("ul")
//格式
ul.innerHTML=this.list.map(item=>`<li>${item}</li>`).join("")
console.log(ul)
}
var obj2=new CreateList2("#box",data1)
console.log(obj2)
obj2.render()
proto
obj2.__proto__等于CreateList2.prototype
上面的函数加上下面的代码
var obj2=new CreateList2("#box",data1)
console.log(obj2.__proto__)
console.log(CreateList2.prototype)
constructor
对象的 proto 里面也有一个成员叫做 constructor
这个属性就是指向当前这个对象所属的构造函数
原型链
访问一个对象的成员的时候,自己没有就会去 proto 中找
接下来就是,如果 proto 里面没有就再去 proto 里面找一直找到 Object.prototype 里面都没有,那么就会返回 undefiend。
131选项卡
<style>
*{
list-style: none;
}
div{
width: 400px;
height: 200px;
background-color: lightblue;
}
ul{
text-align: center;
display: flex;
}
.header li{
height: 50px;
width: 100px;
border: 1px solid gray;
}
.box{
position: relative;
}
.box li{
position: absolute;
height: 100px;
width: 300px;
}
.active{
z-index: 1;
background-color: yellow;
}
.box .active{
z-index: 1;
background-color: yellow;
}
</style>
</head>
<body>
<div id="first">
<ul class="header">
<li class="active">1</li>
<li>2</li>
<li>3</li>
</ul>
<ul class="box">
<li class="active">111</li>
<li>222</li>
<li>333</li>
</ul>
</div>
<div id="sec">
<ul class="header">
<li class="active">1</li>
<li>2</li>
<li>3</li>
</ul>
<ul class="box">
<li class="active">111</li>
<li>222</li>
<li>333</li>
</ul>
</div>
<script>
function Tabs(select){
var container=document.querySelector(select)
this.oHeaderItems=container.querySelectorAll(".header li")
this.oBoxItems=container.querySelectorAll(".box li")
}
//属性写在构造函数里
Tabs.prototype.change=function(){
//把方法写在原型中,可共用
for(let i=0;i<this.oHeaderItems.length;i++){
//使用var为什么达不到效果
this.oHeaderItems[i].onclick=()=>{
//使用箭头函数,使下面的this指向它的父元素
console.log(this)
var index=i
for(let m=0;m<this.oHeaderItems.length;m++){
this.oHeaderItems[m].classList.remove("active")
this.oBoxItems[m].classList.remove("active")
//去除active属性
}
this.oBoxItems[index].classList.add("active")
this.oHeaderItems[index].classList.add("active")
}
}
}
var tab1=new Tabs("#first")
tab1.change()
//也可以直接把上面两行代码改为new Tabs(“.first”)
//然后把tab1改为this.change()移到function Tabs函数中
var tab2=new Tabs("#sec")
tab2.change()
</script>
改进,第一个按鼠标选择,第二个块,鼠标移入选择
<script>
function Tabs(select,type){
var container=document.querySelector(select)
this.oHeaderItems=container.querySelectorAll(".header li")
this.oBoxItems=container.querySelectorAll(".box li")
this.type=type
this.change()
}
Tabs.prototype.change=function(){
for(let i=0;i<this.oHeaderItems.length;i++){
this.oHeaderItems[i].addEventListener(this.type,()=>{
//绑定类型的选择
console.log(this)
var index=i
for(let m=0;m<this.oHeaderItems.length;m++){
this.oHeaderItems[m].classList.remove("active")
this.oBoxItems[m].classList.remove("active")
}
this.oBoxItems[index].classList.add("active")
this.oHeaderItems[index].classList.add("active")
}
)}
}
new Tabs("#first","click")
new Tabs("#sec","mouseover")
</script>
132 class_Es6
构造器函数
class CreateObj{
}
133面向对象继承
构造函数继承
只能继承属性
function person(name,age){
this.name=name
this.age=age
}
function adds(name,age,grade){
person.call(this,name,age)
//改变person中this指向,使添加的name,age到达这个函数(adds)中
//也可以用apply但是后边要为数组[]
this.grade=grade
}
var a=new adds("lucy",18,100)
console.log(a)
原型继承
只能继承方法
function Person(name,age){
this.name=name
this.age=age
}
Person.prototype.say=function(){
console.log("hello")
}
function Per2(name,age,grade){
Person.call(this,name,age)
this.grade=grade
}
Per2.prototype=Person.prototype
var def=new Per2("lucy",18,100)
def.say()
//这个方法会影响原来的
Per2.prototype=new Person()
var abc=new Per2("lucy",18,100)
abc.say()
晕
基础增加法
function Person(name,age){
this.name=name
this.age=age
}
Person.prototype.say=function(){
console.log("hello")
}
Person.prototype.PrintGrade=function(){
console.log(this.name,this.grade)
}
var a=new Person("lucy",18)
console.log(a)
a.say()
覆盖
function Person(name,age){
this.name=name
this.age=age
}
Person.prototype.say=function(){
console.log("hello")
}
Person.prototype.PrintGrade=function(){
console.log(this.name,this.grade)
}
Person.prototype.say=function(){
console.log("你好")
}
//在这!
var a=new Person("lucy",18)
console.log(a)
a.say()
增强原来
function Person(name,age){
this.name=name
this.age=age
}
Person.prototype.say=function(){
console.log("hello")
}
Person.prototype.PrintGrade=function(){
console.log(this.name,this.grade)
}
Person.prototype.say2=function(){
this.say()
console.log("你好")
}
//增强原来
var a=new Person("lucy",18)
console.log(a)
a.say2()
组合继承
构造函数继承+原型继承
function Person(name,age){
this.name = name
this.age = age
}
Person.prototype.say = function(){
console.log("hello")
}
function Student(name,age,classroom){
Person.call(this,name,age)
this.classroom = classroom
}
Student.prototype = new Person()
var obj = new Student("kerwin",100,"1班")
console.log(obj)
继承案例
135继承ES6
继承原型(方法)extends
class person{
constructor(name, age) {
this.name=name
this.age=age
}
say(){
console.log(this.name,"hello")
}
}
class person2 extends person{
}
var obj=new person2()
console.log(obj)
继承属性super
super必须写在第一行
class person{
constructor(name, age) {
this.name=name
this.age=age
}
say(){
console.log(this.name,"hello")
}
}
class person2 extends person{
constructor(name,age,grade){
super(name,age)
//在这!!
this.grade=grade
}
}
var obj=new person2()
console.log(obj)
136初识前后端交互
- ajax 全名 async(异步) javascript and XML(闭合标签)
- 是前后台交互的能力
- 也就是我们客户端给服务端发送消息的工具,以及接受响应的工具
137 ajax
优势:
1.不需要插件的支持,原生 js 就可以使用
2. 用户体验好(不需要刷新页面就可以更新数据)
1.创建对象
在 js 中有内置的构造函数来创建 ajax 对象 创建 ajax 对象以后,我们就使用 ajax 对象的方法去发送请求和接受响应
创建对象var xhr=new XMLHttpRequest()
2.配置链接信息
const xhr = new XMLHttpRequest()
// xhr 对象中的 open 方法是来配置请求信息的
// 第一个参数是本次请求的请求方式 get / post / put / ...
// 第二个参数是本次请求的 url
// 第三个参数是本次请求是否异步,默认 true 表示异步,false 表示同步
// xhr.open('请求方式', '请求地址', 是否异步)
xhr.open('get', './data.php')
localhost本机域名 127.0.0.1本机IP
baidu.cn域名
3.发送请求
const xhr = new XMLHttpRequest()
xhr.open('get', './data.php')
// 使用 xhr 对象中的 send 方法来发送请求
xhr.send()
4.ajax状态码
readyStateChange
用readyStateChange来监听 ajax 对象的 readyState 值改变
xhr.status
是记录本次请求的 http 状态码的(200-299)
if (xhr.readyState === 4 && /^2\d{2}$/.test(xhr.status)) {
// 这里表示验证通过
// 我们就可以获取服务端给我们响应的内容了
}
404表示未找到页面
responseText
用来记录服务端给我们的响应体内容的
139 ajax同步异步
直接用true(异步)即可,用false还要等什么都好了才返回
var xhr=new XMLHttpRequest
xhr.open("GET","",true)
//true表示异步,false表示同步
xhr.send()
xhr.onload=function(){
if(xhr.status===200){
console.log(xhr.responseText)
}
}
请求方式
post安全,数据量大
- get获取数据
- post提交数据
- put更新(全部)
- delete删除
- patch部分修改信息
- header
- options获取服务器设备信息
- connnect保留请求方式?
发送一个带有参数的 get 请求
get 请求的参数就直接在 url 后面进行拼接就可以
const xhr = new XMLHttpRequest()
// 直接在地址后面加一个 ?,然后以 key=value 的形式传递
// 两个数据之间以 & 分割
xhr.open('get', './data.php?a=100&b=200')
xhr.send()
发送一个带有参数的 post 请求
post 请求的参数是携带在请求体中的,所以不需要再 url 后面拼接
const xhr = new XMLHttpRequest()
xhr.open('get', './data.php')
// 如果是用 ajax 对象发送 post 请求,必须要先设置一下请求头中的 content-type
// 告诉一下服务端我给你的是一个什么样子的数据格式
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
// 请求体直接再 send 的时候写在 () 里面就行
// 不需要问号,直接就是 'key=value&key=value' 的形式
xhr.send('a=100&b=200')
application/x-www-form-urlencoded
表示的数据格式就是key=value&key=value
另一种以json形式表示
const xhr = new XMLHttpRequest()
xhr.open('get', './data.php')
// 如果是用 ajax 对象发送 post 请求,必须要先设置一下请求头中的 content-type
// 告诉一下服务端我给你的是一个什么样子的数据格式
xhr.setRequestHeader('content-type', 'application/json')
xhr.send(JSON.stringfy({
username:"lucy",
password:"18"
}))
ajax封装
function queryStringify(obj) {
let str = ''
for (let k in obj) str += `${k}=${obj[k]}&`
return str.slice(0, -1)
}
// 封装 ajax
function ajax(options) {
let defaultoptions = {
url: "",
method: "GET",
async: true,
data: {},
headers: {},
success: function () { },
error: function () { }
}
let { url, method, async, data, headers, success, error } = {
...defaultoptions,
...options
}
if (typeof data === 'object' && headers["content-type"]?.indexOf("json") > -1)
{
data = JSON.stringify(data)
}
else {
data = queryStringify(data)
}
// 如果是 get 请求, 并且有参数, 那么直接组装一下 url 信息
if (/^get$/i.test(method) && data) url += '?' + data
// 4. 发送请求
const xhr = new XMLHttpRequest()
xhr.open(method, url, async)
xhr.onload = function () {
if (!/^2\d{2}$/.test(xhr.status)) {
error(`错误状态码:${xhr.status}`)
return
}
// 执行解析
try {
let result = JSON.parse(xhr.responseText)
success(result)
} catch (err) {
error('解析失败 ! 因为后端返回的结果不是 json 格式字符串')
}
}
// 设置请求头内的信息
for (let k in headers) xhr.setRequestHeader(k, headers[k])
if (/^get$/i.test(method)) {
xhr.send()
} else {
xhr.send(data)
}
}
ajax({
url:"http://localhost:3000/users",
method:"GET",
async:true,
data:{
username:"kerwin",
password:"123"
},
headers:{},
success:function(res){
console.log(res)
},
error:function(err){
console.log(err)
}
})
144 ajax前后端交互案例
145 回调地狱问题
- 当一个回调函数嵌套一个回调函数的时候
- 就会出现一个嵌套结构
- 当嵌套的多了就会出现回调地狱的情况
如图
解决方法:使用Promise语法
146 Promise基础语法
new Promise(function (resolve, reject) {
// resolve 表示成功的回调
// reject 表示失败的回调
}).then(function (res) {
// 成功的函数
}).catch(function (err) {
// 失败的函数
})
147 Promise封装ajax
new Promise(function (resolve, reject) {
ajax({
url: '第一个请求',
success (res) {
resolve(res)
}
})
}).then(function (res) {
// 准备发送第二个请求
return new Promise(function (resolve, reject) {
ajax({
url: '第二个请求',
data: { a: res.a, b: res.b },
success (res) {
resolve(res)
}
})
})
}).then(function (res) {
ajax({
url: '第三个请求',
data: { a: res.a, b: res.b },
success (res) {
console.log(res)
}
})
})
149 async和await语法
回调地狱的终极解决方案
async function fn() {
const res = await promise对象
}
151 fetch
XMLHttpRequest 是一个设计粗糙的 API,配置和调用方式非常混乱, 而且基于事件的异步模型写起来不友好。
156 cookie
特点:
- 只能存储文本
- 单条存储有大小限制4KB左右数量限制(一般浏览器,限制大概在50条左右)
- 读取有域名限制:不可跨域读取,只能由来自 写入cookie的 同一域名 的网页可进行读取。简单的讲就是,哪个服务器发给你的cookie,只有哪个服务器有权利读取
- 时效限制:每个cookie都有时效,默认的有效期是,会话级别:就是当浏览器关闭,那么cookie立即销毁,但是我们也可以在存储的时候手动设置cookie的过期时间
- 路径限制:存cookie时候可以指定路径,只允许子路径读取外层cookie,外层不能读取内层。
jsonp
Jsonp(JSON with Padding) 是 json 的一种"使用模式",可以让网页从别的域名(网站)那获取资料,即跨域读取数据。(同源策略)