JS篇:正则表达式,前后端交互技术

正则表达式

构造语法

  1. 字面量

    var reg=/abc/:这个例子检验必包含abc字母且紧密连在一起

  2. 内置构造函数

    var rge=new RegExp("abc")同义

检验方法

reg.test(myinput.value)返回值是true或false

捕获方法

exec():能捕获符合条件的片段 返回值是数组或空值 只能捕获遇到的第一个,因为他不会记住捕获后的的下标 对于限定符,捕获方法开启贪婪特性,会取出最大限度。我们可以在限定符后加上?来让其取最少次数

标识符

解决捕获的懒惰

  • g:捕获多个符合格式的

var datestr="time is 2029-01-01 12:20:20 to 2019-11-01 12:20:20"
var reg =/\d{4}-\d{1,2}-\d{1,2}/g
var newdatestr1=reg.exec(datestr)//第一个符合条件的
var newdatestr2=reg.exec(datestr)//第二个符合条件的
var newdatestr3=reg.exec(datestr)//null值
console.log(newdatestr1.split[0]("-").jion("/"))//返回值是数组,所以将下标为0的数组元素即字符串分割成一个数组再转换为字符串
console.log(newdatestr2.split[0]("-").jion("/")




var reg =/(\d{4})-(\d{1,2})-(\d{1,2})/g
//加小括号后会添加一个单独捕获的功能
var newdatestr1=reg.exec(datestr)//第一个符合条件的
var newdatestr2=reg.exec(datestr)//第二个符合条件的
//数组第一个元素是捕获全体,后面的是捕获括号内的内部

可以解决字符串中的match,replace方法同样具有的懒惰性,注意要用到正则表达式

  • 字符串的match方法

    var datestr="time is 2029-01-01 12:20:20 to 2019-11-01 12:20:20"
    console.log((datestr.match(/\d{4}-\d{1,2}-\d{1,2}/g))
    //好处是这个方法直接将拿到的两个数据放在同一个数组
    
  • i:捕获不分大小写

元字符

表示一类字符

常见释义

  • \d:包含数字
  • \d\d:包含两位数字
  • \D:包含非数字
  • \D\D:包含两位非数字
  • \Dk\D:两位非数字夹着一个k
  • \s:包含空白(空格,缩进,换行都可以)
  • \S:包含非空白
  • \w:包含字母、数字、下划线
  • \W:包含非字母、数字、下划线
  • \W\W:包含两位非字母、数字、下划线
  • .:任意内容(只有换行符的除外)
  • \任意字符:转义字符,反斜杠后面的内容会被转义为固定字符,而不是当做元字符翻译

边界符

  • ^元字符:开头必须是元字符类型
  • $元字符:结尾必须是元字符类型

限定符

限定字符类型出现次数,元字符加在对应限定符前面,其中限定符只能修饰紧挨着它前面的元字符(边界符也是)

  • *:任意次数
  • +:至少出现一次
  • ?:0~1次
  • {n}:指定次数
  • {n,}:>=n
  • {n,m}:n~m

特殊符号

  • ():将元字符装为一个整体

  • |:包含|两边的元字符中一个就可以

    需要注意的是:|会分别把两边所有内容看做一个整体,即必须包含两边中一个的整体

  • [n个字符]:至少包含n个字符中的一个

  • -:表示延伸

    [a-zA-Z0-9_]=\w

    [0-9]=\d

  • [^n个字符串]:至少不包含n个字符中的一个

    在[]内使用不同于边界符的意思,例如[^abc]检验abz也true

ES6

定义变量

  1. let

    • 不能在定义之前访问

    • 变量不能重定义

    • 块级作用域,包含if语句,switch语句等,不限于函数块

      简易选项卡案例改进

      ·<!DOCTYPE html>
      <html lang="en">
      
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Document</title>
          <style>
              * {
                  margin: 0;
                  padding: 0;
              }
      
              ul {
                  list-style: none;
              }
      
              .header {
                  display: flex;
                  width: 500px;
              }
      
              .header li {
                  flex: 1;
                  height: 50px;
                  line-height: 50px;
                  text-align: center;
                  border: 1px solid black;
              }
      
              .box {
                  position: relative;
              }
      
              .box li {
                  position: absolute;
                  left: 0;
                  top: 0;
                  width: 500px;
                  height: 200px;
                  background-color: yellow;
                  display: none;
              }
      
              /*      给第一个样式先来个激活状态 */
              .header .active {
                  background-color: orange;
              }
      
              .box .active {
                  display: block;
              }
          </style>
      </head>
      
      <body>
          <ul class="header">
              <li class="active">1</li>
              <li>2</li>
              <li>3</li>
              <li>4</li>
          </ul>
          <ul class="box">
              <li class="active">111</li>
              <li>222</li>
              <li>333</li>
              <li>444</li>
          </ul>
          <script>
              var headerItems = document.querySelectorAll(".header li")
              var boxItems = document.querySelectorAll(".box li")
              //用for循环给每li添加自定义属性标识,并且设置标题的点击事件
              //用let定义,每次循环都是新的i
              for (let i = 0; i < headerItems.length; i++) {
                  /* headerItems[i].dataset.index=i; */
                  headerItems[i].onclick = handler
      
                  //点击事件函数
                  function handler() {
                      //辨识点击哪个标题
                      var index = i
                      //移除激活类名
                      for (var m = 0; m < headerItems.length; m++) {
                          headerItems[m].classList.remove("active")
                          boxItems[m].classList.remove("active")
                      }
                      //添加激活状态
                      headerItems[index].classList.add("active")
                      boxItems[index].classList.add("active")
                  }
              }
          </script>
      </body>
      
      </html>
      
  2. const:定义后作为常量存在,不能再重新赋值,不能只定义不赋值

    应用于网页中一些作为参考的数据

  3. let块级作用域案例:最常用的情景

函数的默认参数

普通函数和箭头函数均适用

//当调用函数时忘记传参,会使用默认值
function test(a=1.b=2){
return a+b
}

箭头函数

  1. 语法:var 变量=(0=>{})

    • 只有一个形参的时候可以省略()

    • 当大括号内只有一句代码或只有返回值,{}与return可以省略

      var newlist =list.map(function(item){
      return `<li>${item}</li>`
      })
      //可以转化为
      var newlist =list.map(item=>`<li>${item}</li>`)
      

      当{}里面只有一个对象时,不省略{}

    • arguments:没办法用箭头函数

      在函数没有形参的情况下,调用函数时传实参给函数,在函数内使用此关键字可以得到所传实参的伪数组。

      var test=function(){
      console.log(a,b,c)
      console.log(arguments[0],arguments[1],arguments[2])
      //转化为真数组
      console.log(Array.from(arguments))
      })
      test(1,2,3)
      
    • 箭头函数的this是父级作用域的

      //如果直接在计时器内用this,会指向window,所以用that在外面暂存this
      mytext.oninput=function(){
      var that=this
      setTimeout(()=>{
      console.log(that.value)
      },1000)
      }
      //箭头函数可以直接指向外面的父级元素
      mytext.oninput=function(){
      setTimeout(()=>{
      console.log(this.value)
      }1000)
      }
      

解构赋值

快速从对象和函数中获取里面的成员

  1. 数组

    var arr=["1","2","3"]
    let[x,y,z]=arr
    console,log(x,y,z)
    
  2. 对象

    var obj={
       name:"1",
       age:"2",
       location:"3"
    }
    //因为location变量名已经被window占用,不能重名,可以自己用冒号重命名
    let {name,age,location:mylocation}=obj
    console.log(name)
    console.log(age)
    console.log(mylocation)
    

对象简写

当成员与成员值一样时可以只写一个

如:var obj={getname:getname}可以写成var obj={getname}

如:var obj={getName:function(){}}可以写成var obj={getName(){}}

展开运算符…

  1. 展开拼接

    var a=[1,2,3]
    var b=[4,5,6]
    拼接两数组
    //conlose.log(a,concat(b))
    var c=[...a,...b]
    
  2. 展开复制

    var a=[1,2,3]
    //var b=a.slice()
    //var b=a.concat()
    var b=[...a]
    b[0]="ha"
    
  3. 参数-实参-形参

    • 解决arguments不能用于箭头函数的问题
    var test=(...arr)=>{
    console.log(arguments)
    }
    test(1,2,3,4)
    
    • a对应1,b对应2,…arr对应[3,4,5]

      而且…arr放在最后最后一个参数

    var test=function(a,b...arr)=>{
    console.log(arr)
    }
    test(1,2,3,4,5)
    
    • 找出后端所传数据的最值
    var arr=[1,2,3,4,5,6,7,8,9]
    var res=Math.max(...arr)
    
    • 伪数组转换
    function test(){
    var arr=[...arguments]
    console.log(arr)
    }
    test(1,2,3,4,5)
    

案例:用户数据修改

    <input type="text" id="myusername">
    <input type="tel" id="myage">
    <button id="btn">修改</button>
    <div id="box"></div>
    <script>
        //后端数据
        var obj = {
            name: "xiaohong",
            age: 100,
            location: "guangdong",
            id: "2154285424252"
        }
        //后端数据渲染
        function render({name,age,location}) {
            box.innerHTML = `name${name},age${age},location:${location}`
        }
        render(obj)
        btn.onclick=function(){
            var name=myusername.value
            var age=myage.value
            var newobj={
                ...obj,
                name,
                age
            }
            //重新渲染
            render(newobj)
        }
    </script>

模块化语法

  1. 模块化之前的痛点

    引用js文件时

    • 私密代码依然会被访问
    • 会出现变量名重复
    • 多个js文件互相引用会出现一定的顺序依赖
  2. 模块化语法——私密不怕

    分两步

    • 外部js文件导出:

      export{
      a,b,c...//你想被别人导入的函数名
      }
      
    • 本文件导入:

      <script type="module">
        import{a,b,c...你想导入的函数名} from `文件路径`
      </script>
      之后便可以直接调用函数
      
  3. 模块化语法——重名不怕

    • 文件导入:

      <script type="module">
        import{a,重名函数 as 重命名} from `文件路径`
      </script>
      之后便可以直接调用函数-以重命名方式
      
  4. 模块化语法——依赖不乱

    分两步

    • 在外部js文件中先引入需要的其他js文件

      <import>{...}from`路径`
      之后便可以直接调用函数
      
    • 本文件导入时引入顺序可以不按顺序

面向对象

面向对象是一种编程思维,在这个过程中,我们需要关注每一个元素,元素之间的关系,顺序…

创建面向对象的方式

使用自定义构造函数

function 函数名(形参){执行语句}
var 变量名=new 函数名(实参)

构造函数需要要注意的

  1. 函数名首字母大写
  2. 构造函数不需写return,写了也没作用(除非返回的是复杂数据类型)
  3. 构造函数能当普通函数调用
  4. this指向
    • new过程也是实例化的过程,在实例化之前,this没有指向;实例化之后,实例对象就已经生成了,无关是否赋值

面向对象的原型

对象._proto_===构造函数.prototype

  1. 案例:用面向对象思想渲染页面
       <script>
       var data1 = {
            title:"体育",
            list: ["体育—1", "体育—2", "体育—3"]
        }
        var data2 = {
            title:"综艺",
            list: ["综艺—1", "综艺—2", "综艺—3"]
        }
        //构造函数
        function CreateList(select, data) {
            //获取节点
            this.ele = document.querySelector(select)
            //赋予后端数据
            this.title = data.title,
            this.list = data.list
            //渲染页面
            this.render = function () {
                var h1 = this.ele.querySelector("h1")
                var ul = this.ele.querySelector("ul")
                h1.innerHTML = this.title
                ul.innerHTML = this.list.map(item => `<li>${item}</li>`).join("")
            }
        }
        //
        var obj1 = new CreateList(".box1", data1)
        obj1.render()
        var obj2 = new CreateList(".box2", data2)
        obj2.render()
    </script>

缺点:每new一个自定义函数都会在堆内存中开辟新的空间

=》用对象原型思想渲染页面

    <div class="box1">
        <h1></h1>
        <ul></ul>
    </div>
    <div class="box2">
        <h1></h1>
        <ul></ul>
    </div>
    <script>
        var data1 = {
            title:"体育",
            list: ["体育—1", "体育—2", "体育—3"]
        }
        var data2 = {
            title:"综艺",
            list: ["综艺—1", "综艺—2", "综艺—3"]
        }
        //构造函数
        function CreateList(select, data) {
            //获取节点
            this.ele = document.querySelector(select)
            //赋予后端数据
            this.title = data.title,
            this.list = data.list
        }
        //原型
        CreateList.prototype.render=function(){
            var h1 = this.ele.querySelector("h1")
            var ul = this.ele.querySelector("ul")
            //渲染页面
            h1.innerHTML = this.title
            ul.innerHTML = this.list.map(item => `<li>${item}</li>`).join("")
        }
        
        //
        var obj1 = new CreateList(".box1", data1)
        obj1.render()
        var obj2 = new CreateList(".box2", data2)
        obj2.render()
    </script>

用面对对象思想建选项卡

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        ul {
            list-style: none;
        }

        .header {
            display: flex;
            width: 500px;
        }

        .header li {
            flex: 1;
            height: 50px;
            line-height: 50px;
            text-align: center;
            border: 1px solid black;
        }

        .box {
            position: relative;
            height: 200px;
        }

        .box li {
            position: absolute;
            left: 0;
            top: 0;
            width: 500px;
            height: 200px;
            background-color: yellow;
            display: none;
        }

        /*      给第一个样式先来个激活状态 */
        .header .active {
            background-color: orange;
        }

        .box .active {
            display: block;
        }
    </style>
</head>

<body>
    <div class="container1">
        <ul class="header">
            <li class="active">1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
        </ul>
        <ul class="box">
            <li class="active">111</li>
            <li>222</li>
            <li>333</li>
            <li>444</li>
        </ul>
    </div>
    <div class="container2">
        <ul class="header">
            <li class="active">1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
        </ul>
        <ul class="box">
            <li class="active">111</li>
            <li>222</li>
            <li>333</li>
            <li>444</li>
        </ul>
    </div>
    <script>
        var headerItems = document.querySelectorAll(".header li")
        var boxItems = document.querySelectorAll(".box li")
        //属性放在各自的
        function Tabs(select, type) {
            var container = document.querySelector(select)
            this.headerItems = container.querySelectorAll(".header li")
            this.boxItems = container.querySelectorAll(".box li")
            //自己调用原形的方法
            this.type = type
            this.change()
        }
        //方法放在共用的
        Tabs.prototype.change = function () {
            for (let i = 0; i < this.headerItems.length; i++) {
                /* headerItems[i].dataset.index=i; */
                this.headerItems[i].addEventListener(this.type, () => {
                    //辨识点击哪个标题
                    var index = i
                    //移除激活类名
                    for (var m = 0; m < this.headerItems.length; m++) {
                        this.headerItems[m].classList.remove("active")
                        this.boxItems[m].classList.remove("active")
                    }
                    //添加激活状态
                    this.headerItems[index].classList.add("active")
                    this.boxItems[index].classList.add("active")
                })
            }
        }
        //可以穿第二个参数,控制事件类型
        new Tabs(".container1", "click")
        new Tabs(".container2", "mouseover")
    </script>
</body>
</html>

es6:class构造器函数

将属性和公共方法分开

语法

class 函数名{
constructor(){函数属性}
原型中挂的方法
}

选项卡改造

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        ul {
            list-style: none;
        }

        .header {
            display: flex;
            width: 500px;
        }

        .header li {
            flex: 1;
            height: 50px;
            line-height: 50px;
            text-align: center;
            border: 1px solid black;
        }

        .box {
            position: relative;
            height: 200px;
        }

        .box li {
            position: absolute;
            left: 0;
            top: 0;
            width: 500px;
            height: 200px;
            background-color: yellow;
            display: none;
        }

        /*      给第一个样式先来个激活状态 */
        .header .active {
            background-color: orange;
        }

        .box .active {
            display: block;
        }
    </style>
</head>

<body>
    <div class="container1">
        <ul class="header">
            <li class="active">1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
        </ul>
        <ul class="box">
            <li class="active">111</li>
            <li>222</li>
            <li>333</li>
            <li>444</li>
        </ul>
    </div>
    <div class="container2">
        <ul class="header">
            <li class="active">1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
        </ul>
        <ul class="box">
            <li class="active">111</li>
            <li>222</li>
            <li>333</li>
            <li>444</li>
        </ul>
    </div>
    <div class="container3">
        <ul class="header">
            <li class="active">1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
        </ul>
        <ul class="box">
            <li class="active">111</li>
            <li>222</li>
            <li>333</li>
            <li>444</li>
        </ul>
    </div>
    <script>
        var headerItems = document.querySelectorAll(".header li")
        var boxItems = document.querySelectorAll(".box li")
        class MyTabs {
            constructor(select, type) {
                var container = document.querySelector(select)
                this.headerItems = container.querySelectorAll(".header li")
                this.boxItems = container.querySelectorAll(".box li")
                this.type = type
                this.change()
            }
            change() {
                for (let i = 0; i < this.headerItems.length; i++) {
                    /* headerItems[i].dataset.index=i; */
                    this.headerItems[i].addEventListener(this.type, () => {
                        //辨识点击哪个标题
                        var index = i
                        //移除激活类名
                        for (var m = 0; m < this.headerItems.length; m++) {
                            this.headerItems[m].classList.remove("active")
                            this.boxItems[m].classList.remove("active")
                        }
                        //添加激活状态
                        this.headerItems[index].classList.add("active")
                        this.boxItems[index].classList.add("active")
                    })
                }
            }
        }
        new MyTabs(".container1", "click")
        new MyTabs(".container2", "mouseover")
        new MyTabs(".container3", "mouseover")
    </script>
</body>

</html>

面向对象继承

构造函数继承—只能继承属性:通过在引入后强行改变this指向

原型继承—继承原型上的方法:

理解代码

function Person(name,age){
     this.name=name
     this.age=age
}
Person.prototype.say=function(){}
function Student(name,age,grade){
Person.apply(this,[name,age])
this.grade=grade
}
//继承person原形:但会有一些空数组形成
Student.prototype=new Person()
//为student挂上新的方法
Student.prototype.printGrade=function(){}
//覆盖原有方法
Student.prototype.say=function(){}
//增强原有方法
Student.prototype.say2=function(){
    //继承原来方法
    this.say()
    增加的语句...
}

组合继承:构造函数继承+原型继承

ajax

拥有前后端交互不跳转链接的良好体验

前后端交互

客户端=>服务器=>数据库

基础流程

  1. 创建xhr

    var xhr=new XMLHttpRequest()

  2. 配置

    xhr.open("请求方式","请求地址","是否异常")

    请求方式常为:GET

    请求地址:http为协议名,localhost为本机域名,127.0.01为本机IP

  3. 发送

    xhr.send()

  4. 接收数据,注册一个事件

ajax状态码

  1. ajax的事件

    • readyStateChange:这个事件是专门用来监听 ajax 对象的 readyState 值改变的的行为,客户端与后端接上头就会执行的语句

      xhr.onreadystatechange=function(){`
             if(ajax.readystate===4/*保证前端数据齐全*/&&xhr.status===200/*确保数据正确,404表示找不到页面*/){
             }
      }
      
    • onload:只有处于状态码4,请求已完成,响应已就绪的情况下,才会进入onload。

      xhr.onload=function(){`
             if(xhr.status===200){
             }else if(xhr.status===404){}
      }
      
  2. ajax状态有5个状态

    • 0:未初始化,open还没打开
    • 1:配置完成
    • 2:send完成
    • 3、解析响应内容
    • 4、解析完毕,客户端可以使用

模拟前后端案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <button id="btn">获取数据</button>
    <ul id="mylist"></ul>
    <script>
        btn.onclick = function () {
            var xhr = new XMLHttpRequest()
            xhr.open("GET", "....")
            xhr.send()
            xhr.onload = function () {
                if (xhr.status === 200) {
                    var jsondata = JSON.parse(xhr.responseText)
                    render(jsondata)
                }
            }
        }
        function render(jsondata) {
            console.log(jsondata.data.list)
            var html = jsondata.data.list.map(item => <li>
                <img src="${item.imageUrl}" />
                <div>${item.name}</div>
            </li>)
        }
    </script>
</body>
</html>

ajax同步异步

  1. 同步:调用某个内容时,调用方等这个调用返回结果才继续往后执行,期间不执行其他语句.不推荐

  2. 异步:调用发出后调用者可用继续执行后面的语句

var xhr=new XMLHttpRequest()
xhr.open("GET","1.json",false)
//传true表示异步请求,false表示同步请求
xhr.send()
xhr.onload=function(){}

ajax请求方式

由后端决定

下面的例子在Preview on Web Server插件下使用,仅模仿了部分后端的功能

get:偏向获取数据

btn.onclick = function () {
            var xhr = new XMLHttpRequest()
            //取得话会取出全部,此时我们可以在路径后加?key=value取出部分的
            xhr.open("GET", "....")
            xhr.send()
            xhr.onload = function () {
                if (xhr.status === 200) { }
            }
            xhr.send()
        }

post:偏向提交数据

 btn.onclick = function () {
            var xhr = new XMLHttpRequest()
            xhr.open("POST", "....")
            xhr.onload = function () {
                if (xhr.status === 200) { }
            }
            //用这条语句表明传输格式key-value
            xhr.xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
        xhr.send(`username=shanzhen&password=456`)
        }
        //或用这条语句表明传输格式form
         xhr.xhr.setRequestHeader("Content-Type","application/json")
        xhr.send(JSON.stringify({
        username:"ximen",
        password:"789"
        }))
        }

put:偏向全部覆盖

btn.onclick = function () {
            var xhr = new XMLHttpRequest()
            //在连接后加/id表示修改谁
            xhr.open("PUT", "..../1")
            xhr.onload = function () {
                if (xhr.status === 200) { }
            }
xhr.setRequestHeader("Content-Type","application/json")
xhr.send(JSON.stringify({
        username:"ximen",
        password:"789"
        }))
        }

patch:偏向部分更新

btn.onclick = function () {
            var xhr = new XMLHttpRequest()
            //在连接后加/id表示修改谁
            xhr.open("PATCH", "..../1")
            xhr.onload = function () {
                if (xhr.status === 200) { }
            }
xhr.setRequestHeader("Content-Type","application/json")
xhr.send(JSON.stringify({
        username:"ximen",
        password:"789"
        }))
        }

delete:偏向删除信息

 btn.onclick = function () {
            var xhr = new XMLHttpRequest()
            //在连接后加id表示修改谁
            xhr.open("DELETE", "..../2")
            xhr.onload = function () {
                if (xhr.status === 200) { }
            }
            xhr.send()
            }

ajax封装

代码理解:

// 封装 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
// 发送请求
const xhr = new XMLHttpRequest()
xhr.open(method, url, async)
xhr.onload = function () {
if (!/^2\d{2}$/.test(xhr.status)) {
error(
</span><span class="token string">错误状态码:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${<!-- --></span>xhr<span class="token punctuation">.</span>status<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">
)
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)
}
}
</span><span class="token string">错误状态码:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${<!-- --></span>xhr<span class="token punctuation">.</span>status<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">
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)
    }
})

回调地狱

当回调函数互相嵌套过多时会导致。

如:

//正常发送
ajax({
  url: '1',
  success (res) {
    // 第二个请求:需要第一个请求的结果中的某一个值作为参数
    ajax({
      url: '2',
      data: { a: res.a, b: res.b },
      success (res2) {
        // 第三个请求:需要第二个请求的结果中的某一个值作为参数
        ajax({
          url: '3',
          data: { a: res2.a, b: res2.b },
  				success (res3) { 
            console.log(res3) 
          }
        })
      }
    })
  }
})

es6的promise语法

专门解决回调地狱

  • 语法

    每一个异步事件,在执行的时候都会有三个状态:执行中 / 成功 / 失败

    借助成功状态,用Promise解决回调地狱

    代码理解:

new Promise(function (resolve, reject) {
  ajax({
    url: '1',
    success (res) {
      resolve(res)
    }
  })
}).then(function (res) {
  // 发送第二个请求
  return new Promise(function (resolve, reject) {
    ajax({
      url: '2',
      data: { a: res.a, b: res.b },
      success (res) {
        resolve(res)
      }
    })
  })
}).then(function (res) {
  ajax({
    url: '3',
    data: { a: res.a, b: res.b },
    success (res) {
      console.log(res)
    }
  })
})

es7 的async/await语法

回调地狱的终极解决方案

await 一个 promise 对象,只要是一个 promiser 对象,那么我们就可以使用 async/await 来书写

  • 语法

    async function fn() {  const res = await promise对象 }
    

fetch

XMLHttpRequest 是一个设计粗糙的 API,配置和调用方式非常混乱, 而且基于事件的异步模型写起来不友好。

兼容性不好 polyfill: https://github.com/camsong/fetch-ie8

cookie

cookie的特点

  1. 只能存储文本

  2. 数量限制(一般浏览器,限制大概在50条左右)

  3. 读取有域名限制:不可跨域读取,哪个服务器发给你的cookie,只有哪个服务器有权利读取

  4. 时效限制

  5. 会话级别:当浏览器关闭,那么cookie立即销毁,

    我们也可以在存储的时候手动设置cookie的过期时间

  6. 路径限制:存cookie时候可以指定路径,只允许子路径读取外层cookie,外层不能读取内层。

jsonp

json 的一种使用模式,可以让网页从别的网页获取资料

同源策略规定我们从不同的域(网站)访问数据需要一个特殊的技术( JSONP )

语法:

const script = document.createElement('script')
script.src = './kerwin.txt'
document.body.appendChild(script)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值