专栏首页全栈者前端数据获取之Ajax与Fetch (一)

前端数据获取之Ajax与Fetch (一)

Ajax,读作”阿贾克斯“,这个是每一个web开发者必掌握的一门技术,现在咱们打开一个网页,页面上数据多多少少都会有它的一些参与,来获取数据,但也并不是所有的数据都是通过它来取到的。

Ajax是Asynchronous JavaScript and XML的缩写,中文意思异步的Javascript和XML。

何为异步?

对比同步来说,javascript本身是占用一个线程执行的,如果要以同步的方式发起请求,那就是让这个线程阻塞,等待这个网络请求发出去,然后请求回来,javascript才能接着执行。你可以想象这个的过程,javascript的执行线程一直被占用着,网络请求回来之前,用户只要涉及到javascript脚本操作势必没有任何响应。再解释异步方式,可以理解为javascript发起网络请求时只是立了一个flag,浏览器让其他线程去发了请求,javascript线程继续干自己的事情,等其他线程请求完成回来后,再给javascript立的flag打一个call,javascript线程接到通知继续执行。异步的这种方式能够及时放开javascript脚本执行线程,在页面上,用户多次点击发起请求或者脚本操作都不会受到影响,是比较理想的。宏观上只要记住异步javascript就是不影响当前页面动作的一段javascript代码,这段代码会立flag,并且有一一个回调函数会在将来某个时刻执行。

认识XML

XML,可扩展标记语,是一种语言格式。很多人熟悉JSON格式,你可以做用它和XML类比。XML也有自己的规范,和HTML很像,两个标签中间携带数据。为什么要用它来数据传输呢?我觉得可以理解为不同界域直接的解耦,它是跨平台,跨操作系统,跨语言的一种数据传输的统一标准实现。只不过现在的前端都习惯更方便直观的JSON格式作为数据传输,而告别XML了,现在很少见XML的返回格式了,AJAX应该改名为AJAJ比较合适。

AJAX实现原理

本质是浏览器底层与操作系统暴露出来的一个API,在浏览器中有一个XMLHttpRequest的构造函数,当我们用一些包如jQuery的ajax或者Axiso请求数据时,用的其实就是它的实例。

XMLHttpRequest是浏览器提供了事件通知机制引擎是所暴露出来的API,当发起请求立flag的时候,就是告诉底层,我订阅了这个消息,你要在请求回来的时候通知我,它会暴露出一些钩子给你,你便可以传相应的处理函数进去,等它触发事件,钩子函数得到执行,你传入的回调也得到执行。

AJAX的兼容性

它在一般我们常用的浏览器中是这样实现的。

new window.XMLHttpRequest();

但是有一部分IE中没有XMLHttpRequest,提供了另一个API做相同的事情。

new window.ActiveXObject(Microsoft.XMLHTTP);

AJAX的实现

AJAX的简单实现,只为了解原理去实现,不考虑细节了,大家可以翻jQuery的ajax去看完整源码。

function Ajax() {
    const xhr = new XMLHttpRequest();
    console.log('readyState0:', xhr.readyState);
    xhr.open('GET', 'https://juejin.im/post/5cf0733de51d4510803c22e34es', true);
    console.log('readyState1:', xhr.readyState);
    xhr.onreadystatechange = function(res){
      console.log('readyState:', xhr.readyState);
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          console.log('请求成功');
        } else {
          console.error('请求异常, response code:', xhr.status)
        }
      }
    }
    xhr.send();
}

Ajax();
执行结果:
readyState0: 0
readyState1: 1
readyState: 2
readyState: 3
readyState: 4
VM请求异常, response code: 404

在上面搜了一个不存在的掘金文章编号,返回值404了。大家也可以打开掘金https://juejin.im 打开控制台调试看一下。

解释一下里面的关键点,当new XMLHttpRequest实例后。这个实例有5种状态,可以在它里面readyState 的属性获取到当前状态。

当实例化成功时,readyState为0,实例执行open方法,readyState为1,这两个均为同步操作内容,请求尚未发送。

当实例的send方法执行后,请求发送。readyState的变化均可以在onreadystatechange中捕获到。

发送的请求被接受后,xhr引擎触发onreadystatechange,readyState为2;发送的请求被处理,xhr引擎触发onreadystatechange,readyState为3;发送的请求处理完成返回,xhr引擎触发onreadystatechange,readyState为4。

可以清晰的看到onreadystatechange一共触发了3次,但是需要的数据内容只有在readyState为4时才会存在,所以我们只需要将readyState=4的内容返回处理即可,xhr的status代表可服务器返回的请求的转态码,当200时说明请求正常,其余情况均属于异常情况,上面代码即为404情况。

上面的代码在执行open方法的时候传入了true,这代表本次请求是异步的,下面看一下同步的情况。

function Ajax() {
    const xhr = new XMLHttpRequest();
    console.log('readyState0:', xhr.readyState);
    xhr.open('GET', 'https://juejin.im/post/5cf3578af265da1ba431d656', false);
    console.log('readyState1:', xhr.readyState);
    xhr.onreadystatechange = function(res){
      console.log('readyState:', xhr.readyState);      
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          console.log('请求成功');
        } else {
          console.error('请求异常, response code:', xhr.status)
        }
      }
    }
    xhr.send();
    console.log('异步测试');
}

Ajax();
返回值:
readyState0: 0
readyState1: 1
readyState: 4
请求成功
异步测试

这时候我们看到跟一步不一样的onreadystatechange只被触发了一次,而且readyState的值也只有3中,且console.log('异步测试');这段代码在整个请求完成后才被得到执行,可见同步已将js执行阻塞。

AJAX的内容,本期先介绍这么多,下一期介绍一下ES6后新的数据请求方式Fetch。

如上内容均为自己总结,难免会有错误或者认识偏差,如有问题,希望大家留言指正,以免误人。

本文分享自微信公众号 - 全栈者(fullStackEngineer),作者:TingRongGao

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-06-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 揭秘前端文件上传原理(一)

    在平时工作中,总是会接触过很多文件上传的功能,因为用惯了各种操作库来处理,所以总有一种云里雾里的感觉,没有清晰的思路,归根到底还是没有理解文件上传的原理。接下来...

    用户1462769
  • JS数组中那些你知道或不知道的

    鱼头注:NewTarget是啥?NewTarget是原生Class FunctionCallbackInfo(函数调用的callback上下文的信息)内的一个不...

    用户1462769
  • 重温基础:ES9系列

    所有整理的文章都收录到我《Cute-JavaScript》系列文章中,访问地址:http://js.pingan8787.com

    用户1462769
  • Ajax

    1、XMLHttpRequest对象 各浏览器(包括ie7+)都支持原生的XHR对象,在这些浏览器中创建XHR对象可以:

    Ewall
  • 弄明白CMS和G1,就靠这一篇了

    CMS和G1作为垃圾收集器里的大杀器,是需要好好弄明白的,而且面试中也经常被问到。

    猿人谷
  • CVPR 2019 一周新出论文汇总附下载(含目标检测、GAN、SLAM、语义分割、三维重建等)

    CV君汇总了最近一周新出的CVPR 2019 论文,总计32篇大会接收论文在这一周上传到arXiv,含7篇Oral报告论文。涵盖方向包括:目标检测、GAN图像生...

    CV君
  • 今日新出 CV 论文汇总(含医学图像、目标检测、唇语识别、SLAM等)

    最近,52CV分享了多篇CVPR 2019 的论文,有位群友问难道除了CVPR 就没有值得读的论文了吗?当然不是,其实很多优秀的工作并不一定出自CVPR。CVP...

    CV君
  • VREP学习笔记-Main scripts 、 Child scripts and Script execution order

    主脚本是仿真脚本。默认情况下,V-REP中的每个场景都有一个主脚本。它包含允许仿真运行的基本代码。如果没有主脚本,仿真运行时将不会执行任何操作。

    六四零
  • 全基因组选择介绍及实践-2:构建H矩阵

    H矩阵作为一步法的入门技术, 是需要掌握的, 本文以一篇文献为例, 介绍如何从头构建H矩阵. 文章包括H矩阵推导过程和代码实现.

    邓飞
  • 对于“没地了”的深圳,在地铁上盖房子是最佳出路么?

    深圳已经没有地了。在这座正在清退建设用地的城市里,要维持甚至改善城市的运行效率,提高城市居民的生活质量,到底有什么法门?在7月27日的深圳城市大数据活跃报告发布...

    DT数据侠

扫码关注云+社区

领取腾讯云代金券