最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • AJAX基础

    正文概述 掘金(大大大石头)   2021-01-22   530

    Ajax基础

    Ajax概述

    背景

    可以简单地认为目前JS能力有限,因此在此之前web平台提供的API还全部停留在单机的阶段

    这样就造成了我们无法实现某些功能,例如:

    • 无法在实现用户登录功能时,当用户输入邮箱地址显示用户对应的头像
    • 无法在实现用户注册功能时,当用户输入邮箱或者用户名就提示是否存在
    • 无法在实现留言板功能时,实时看到最新的用户留言

    数据是存在服务端的,之前的方法无法通过api来获取服务器的数据

    已知发送请求方式

    • 地址栏输入、回车、刷新
    • 特定元素的href和src属性
    • 表单提交

    但这些方式我们无法通过或者很难通过代码的方式进行编程操作

    需求

    对服务端发出请求并且接受服务器端返回的响应

    如果我们可以通过js直接发送网络请求,那么web就可以实现更多的功能,不再是单机的

    Google Suggest

    AJAX最早出现于2005年的Google Suggest

    • 是一种正式的技术
    • 在浏览器端进行网络编程(发送请求、接收响应)的技术方案
    • 我们可以通过JS直接获取服务器端的最新内容而不需要重新加载页面
    • 让web更接近桌面应用的体验

    实现局部更新的效果

    AJAX(Asynchronous Javascript And XML)

    是浏览器提供的一套API,可通过JS的调用,实现通过代码控制相应和请求,实现通过js进行网络编程

    XML:最早在客户端和服务端传递数据时所采用的数据格式

    应用场景

    • 按需获取数据
    • 对用户进行校验
    • 自动更新页面内容
    • 提升用户体验,无刷新的体验

    体验AJAX

    使用jQuery中封装的方法

    免费接口:https://jsonplaceholder.typicode.com/

    // JQ中封装的AJAX方法
    $.ajax({
      // 地址
      url: 'https://jsonplaceholder.typicode.com/posts',
      // 请求方式
      type: 'GET',
      // 筛选数据(title为"doloribus ad provident suscipit at"的数据)
      data: {
        'title': "doloribus ad provident suscipit at"
      },
      // 数据格式
      dataType: 'json',
      // 返回数据,data为返回的数据,可以进行操作
      success: function (data) {
        console.log(data)
      }
    })
    

    原生AJAX详解

    工作中最常用的是封装好的AJAX库

    发送AJAX请求步骤

    1. 创建XMLHttpRequest类型的对象
    2. 准备发送,打开一个网址之间的连接
    3. 执行发送动作
    4. 指定xhr状态变化事件处理函数
    // 原生AJAX方法
    // 创建XMLHttpRequest实例对象对象
    const xhr = new XMLHttpRequest()
    // 调用对象的open方法准备打开链接
    // 参数:请求方法,链接地址
    xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts')
    // 调用send方法发送请求
    // 参数:GET方式参数为null
    xhr.send(null)
    // 监听对象的readystatechange事件
    xhr.onreadystatechange = function () {
      //一旦对象readyStat属性变为4表示数据获取成功
      if (this.readyState === 4) {
        // 打印获取到的数据,数据存在对象的responseText属性中
        console.log(this.responseText)
      }
    }
    

    XMLHttpRequest对象

    AJAX中核心提供了一个XMLHttpRequest类,所有AJAX操作都要依靠这个类(属性和方法)

    使用XMLHttpRequest类的时候我们先要创建一个实例对象

    const xor = new XMLHttpRequest()

    IE6兼容写法

    xhr = new ActiveXObject('Microsoft.XMLHTTP')

    // 创建XMLHttpRequest对象
    // 创建变量
    let xhr = null
    // 进行浏览器能力判断,判断浏览器是否存在XMLHttpRequest
    if (window.XMLHttpRequest) {
      // 如果存在使用XMLHttpRequest类创建
      xhr = new XMLHttpRequest()
    } else {
      // 不存在使用IE6方法创建
      xhr = new ActiveXObject('Microsoft.XMLHTTP')
    }
    // 这是我写的三元表达式创建方法,在新浏览器可以实现,但没有测试IE6
    // let xhr = window.XMLHttpRequest !== undefined ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
    console.log(xhr)
    

    open()方法

    本质上XMLHttpRequest就是js在web平台发送HTTP请求的手段,所以同样符合HTTP约定的格式

    语法:实例.open( 请求方式 ,链接地址 )

    • 参数1:要使用的HTTP方法,例如:GET获取数据、POST提交新数据、PUT更改、DELETE删除等,大小写皆可
    • 参数2:要向其发送的地址

    两个参数都是字符串格式

    xhr.open('get', 'https://jsonplaceholder.typicode.com/posts')
    

    send()方法和请求头

    发送HTTP请求

    语法:实例.send( 数据 )

    参数:在XHR请求重要发送的数据体,根据请求头中的类型进行传参数

    如果是get方法,不需要传参,或者使用null即可

    设置请求头setRequsetHeader()

    此方法必须写在open和send方法之间调用

    语法:实例.setRequsetHeader( header

    数据类型,value具体数据类型 )

    • 参数1:一般设置为'Content-Type',服务器需要我们传送的数据类型
    • 参数2:具体的数据类型,常用’application/x-www-form-urlencoded'和'application/json'
    // // 使用get方式,需要查询的内容直接写在网址后面,使用?连接(?id=1)
    // xhr.open('get', 'https://jsonplaceholder.typicode.com/users?id=1')
    // // get方法不需要设置请求头setRequsetHeader()
    // // send方法也不需要传递参数
    // xhr.send()
    
    
    
    //使用post方法,把需要增加的内容写在send方法内部,而不直接写在open网址上
    xhr.open('POST', 'https://jsonplaceholder.typicode.com/users')
    // 并且需要设置请求头
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
    // send内部传递参数只用字符串并且每个参数名=参数值,使用&连接
    xhr.send('name=cheng&age=19')
    

    响应状态分析

    创建onreadystatechange事件,监听readyState属性的变化

    readyState属性返回一个值代表当前XMLHttoRequest当前的状态,而这个值在整个请求响应中对变化多次,而只有当这个值为4的时候,才是我们需要的,所以我们监听readyState变化,一旦值为4我们就获取返回的数据

    AJAX基础

    readyState值状态描述说明
    0UNSENT实例被创建但尚未调用open方法1OPENED调用open方法建立了连接2HEADERS_RECEIVED调用send方法并且已经可以获状态行和响应头3LOADING响应体下载中,responseText属性可能已经包含部分数据4DONE响应体下载完成,可以直接使用responseText里面的数据
    xhr.onreadystatechange = function () {
      // 查看一下状态,这里只有2、3、4
      console.log(this.readyState)
      //一旦对象readyStat属性变为4表示数据获取成功
      if (this.readyState === 4) {
        // 打印获取到的数据,数据存在对象的responseText属性中
        console.log(this.responseText)
      }
    }
    

    同步和异步

    • 同步:在同一时刻只能做一件事情,后面事情需要等待
    • 异步:执行一个耗时的操作(不需要看管)去做别的事,不等待这件事完成

    AJAX中设置同步和异步执行

    • 在open()方法中传递第三个参数
    • 值为布尔值,true(默认值)代表异步,flase代表同步
    • 如果设置同步执行,则代码会卡死在send()这一步

    不建议使用同步,甚至浏览器会提醒不建议,因为会卡在send这一步,等待全部数据加载成功了后面的代码才能执行,如果此时监听onreadystatechange事件写在send后面会导致执行失败

    建议

    • 先注册onreadystatechange事件,保证事件一定能触发(不论是同步还是异步)
    • 切记不要使用同步

    数据格式

    我们真正关心的问题就是服务端发出何种格式的数据,这种格式如何在客户端用JavaScript解析。

    xml格式

    一种数据描述手段,非常古老,但现在不怎么使用了,因为数据冗余太多

    json格式 - JavaScript Object Notation

    js对象表示法,也是一种数据的描述手段,类似于js中的对象字面量

    服务端采用json格式返回数据,客户端使用json格式解析

    特点:

    • json格式不需要存储在变量中,可以直接写在.json格式文件中,使用{}包裹全部数据
    • 结束不需要写分号
    • 属性名必须加引号的字符串,属性值可以是任意格式
    // 创建一个对象
    const obj = {
        name: 'zs',
        age: 19,
        sex: true
      },
      // 创建一个json格式的字符串
      str = '{"name":"ls","age":19,"sex":"flase"}'
    // json格式和对象格式可以互相转换
    // 使用ES5中新加的json对象的方法stringify转字符串
    console.log(JSON.stringify(obj))
    // 使用ES5中新加的json对象的方法parse把json转对象
    console.log(JSON.parse(str))
    

    注意事项:

    • 不管是json还是XML,只不过是AJAX过程中用到的数据格式,和AJAX没有必然关系
    • 不管是XML还是json,本质上都是把数据返回给客户端
    • 服务器端应该根据相应内容格式设置一个合理的Content-Type

    json server使用

    需求:平时我们自己写一些数据,希望通过AJAX方式获取,就需要在本地搭建一个临时的服务器

    json-server是一个node模块,运行Express服务器,可以指定一个json文件作为api数据源,可以使用它快速搭建一个服务器

    网址:https://github.com/typicode/json-server

    步骤:

    下载安装node.js

    1. 打开命令行(mac终端),输入(mac加sudonpm install -g json-server,等待完成即在本地全局安装了json-server

    2. 新建db.json文件,在文件内书写json代码

      //注意:json-server内部首层只支持数组或者对象类型,再往里可以书写其他类型
      {
        "posts": [
          { "id": 1, "title": "json-server", "author": "typicode" }
        ],
        "comments": [
          { "id": 1, "body": "some comment", "postId": 1 }
        ],
        "profile": { "name": "typicode" }
      }
      
    3. 在VScode中点击终端 -- 新终端即可在VScode内新建终端(命令行)

    4. 在终端输入json-server --watch db.json回车,即可开启本地服务器,监听db.json文件

    5. 命令行下面会显示打开的端口,及可以访问的资源,按住control单击鼠标即可访问(home为主页,其他后缀为db.json中的所有可访问资源)

    AJAX基础

    json文件书写方法

    {
      "students":[
        {"id":1,"name":"zs","age":"19","sex":1},
        {"id":2,"name":"ls","age":"20","sex":0},
        {"id":3,"name":"ww","age":"18","sex":1}
      ],
      "tiezis":[
        {"id":1,"studentId":1,"title":"123","content":"123123123"},
        {"id":2,"studentId":3,"title":"456","content":"456456456"},
        {"id":3,"studentId":2,"title":"789","content":"789789789"},
        {"id":4,"studentId":1,"title":"000","content":"000000000"}
      ],
      "pingluns":[
        {"id":1,"tieziId":1,"content":"123真好看"},
        {"id":2,"tieziId":2,"content":"456真好看"},
        {"id":3,"tieziId":1,"content":"123真好看"},
        {"id":4,"tieziId":3,"content":"789真好看"},
        {"id":5,"tieziId":3,"content":"789真好看"},
        {"id":6,"tieziId":4,"content":"000真好看"}
      ],
      "zhushi":[
        {"id":1,"content":"我是注释,貌似json不支持注释,我就写写在路由里了"},
        {"id":2,"content":"json内部第一层应该是对象或者数组格式,因为这后期这个名字会被作为路由的名字来使用"},
        {"id":3,"content":"如果路由是数组,可以加s代表多个"},
        {"id":4,"content":"id属性是必须的,因为这是相当于索引(类似数组下标),id从1开始"},
        {"id":5,"content":"如果想做关联,可以在其他路由中使用  关联路由名字+Id  的方式关联到路由,例如 studentId,注意可以去掉关联路由的s,后期可以使用关联调用,例如:http://localhost:3000/students/1/tiezis   可以访问students的第一个id(zs)的所有帖子"},
        {"id":6,"content":"json内部全都是双引号书写,不要使用单引号,使用英文状态下符号"}
      ]
    }
    
    

    原生AJAX使用

    get方法

    • 在get请求中,参数通过url地址传递,使用?连接需要传递的参数
    • 在get请求中无需设置请求头,无需设置响应体,send无需传参或者传null即可

    使用get获取上面index.json内容(首先使用jsons-erver打开一个本地服务器)

    // 创建实例对象
    const xhr = new XMLHttpRequest()
    // 调用open方法,使用get方法,并且筛选所有age=18的成员
    xhr.open('get', 'http://localhost:3000/students?age=18')
    // 调用send方法
    xhr.send()
    // 监听状态变化
    xhr.onreadystatechange = function () {
      // 状态值等于4执行打印获取结果
      if (this.readyState === 4) {
        console.log(this.responseText)
      }
    }
    

    post方法

    • 请求体承载需要提交的数据
    • 需要设置请求头,一边服务器接收数据
    • 需要使用send方法传递参数
    // 创建实例对象
    const xhr = new XMLHttpRequest()
    // 调用open方法,使用post方法,向students内部添加数据
    xhr.open('post', 'http://localhost:3000/students')
    // 设置请求头,以url的形式进行添加
    // xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
    // // send内部使用字符串的方式添加数据
    // // 是不是很类似于get的数据请求?没错,就是类似于get
    // xhr.send("name=lulu&age=19&sex=1")
    
    // 使用json格式设置请求头,就可以使用对象字面量的格式传递数据了
    xhr.setRequestHeader('Content-Type', 'application/json')
    // 下两种方法都可以实现添加数据的效果
    // 方法1:使用对象字面量的模版字符串
    // xhr.send(`{
    //   "name":"lala",
    //   "age":19,
    //   "sex":0
    // }`)
    // 方法2:使用JSON的stringify方法把对象转换为字符串
    xhr.send(JSON.stringify({
      name: "heihei",
      age: 19,
      sex: 0
    }))
    xhr.onreadystatechange = function () {
      if (this.readyState === 4) {
        console.log(this.responseText)
      }
    }
    
    
    // 注意:id不需要用添加,程序会自动添加一个id
    

    处理相应数据的渲染

    把客户端返回来的数据呈现到界面上

    • 如果数据较简单,可以使用字符串拼接操作
    • 如果数据比较复杂可以使用模版字符串或者模版引擎
      // 获取元素
      const box = document.getElementById('box')
      // 创建实例对象并使用get方法获得数据
      const x = new XMLHttpRequest()
      x.open('get', 'http://localhost:3000/students')
      x.send()
      // 添加状态改变事件
      x.onreadystatechange = function () {
        if (this.readyState === 4) {
          // 调用添加元素函数,并把获取到的数据转为对象
          add(JSON.parse(this.responseText))
        }
      }
    
      function add(data) {
        // 遍历数据
        for (const i of data) {
          // 创建新的tr元素,并且更改trinnerHTML
          const newTr = document.createElement('tr')
          newTr.innerHTML = `<td>${i.id}</td><td>${i.name}</td><td>${i.age}</td><td>${i.sex === 0?'女':'男'}</td>`
          // 把tr添加给box
          box.appendChild(newTr)
        }
      }
    

    封装AJAX函数(库)

    • 这里主要是为了了解封装的过程,一般情况在开发中都是使用第三方提供的AJAX库,因为它们可能更加严谨。
    • 为了在后续的开发过程中可以更方便的使用这套API,一般的做法都是将其封装到一个函数中以便调用。
    // AJAX库函数
    // 功能:根据传递参数,向数据库获取或者添加数据
    // 参数1:请求方法(get和post)
    // 参数2:请求url地址
    // 参数3:请求参数
    // 参数4:回调函数
    function ajax(method, url, obj, fun) {
      // 将参数1转大写,方便后期进行判断
      method = method.toUpperCase()
      // 创建一个ajax的实例对象,并且使用IE6兼容写法
      const xhr = window.XMLHttpRequest ?
        new XMLHttpRequest() :
        new ActiveXObject('Microsoft.XMLHTTP')
      // 创建一个空数组,用于接收参数
      let att = []
      // 遍历参数,将参数的每一项添加进数组
      for (const i in obj) {
        att.push(`${i}=${obj[i]}`)
      }
      // 数转字符串,使用=连接,模拟传参格式
      const str = att.join('&')
      // 调用open方法,参数使用三元表达式,判断是否是get方法,方法不同传参不同
      xhr.open(method, method === 'GET' ? url + '?' + str : url)
      // 判断是否为post方法,如果是设置请求头
      if (method === 'POST') {
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
      }
      // 调用send方法,根据方法不同使用不同的参数
      xhr.send(method === 'GET' ? null : str)
      // 监听readyState变化事件,当数值等于4执行
      xhr.onreadystatechange = function () {
        if (this.readyState === 4) {
          // 调用回调函数,参数使用JSON.parse转回对象方便使用
          fun(JSON.parse(this.responseText))
        }
      }
    }
    
    // 验证函数是否能正常执行
    ajax('get', 'http://localhost:3000/students', {
      age: 19
    }, function (data) {
      console.log(data)
    })
    ajax('post', 'http://localhost:3000/students', {
      age: 19,
      name: 'laolao',
      sex: 0
    }, function (data) {
      console.log(data)
    })
    

    下载网 » AJAX基础

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元