AJAX引擎原理以及XmlHttpRequest对象的axios、fetch区别详解


Posted in Javascript onApril 09, 2022

AJAX原理

  • Ajax的原理简单来说是在用户和服务器之间加了—个中间层(AJAX引擎),通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。使用户操作与服务器响应异步化。
  • Ajax的过程只涉及JavaScript、XMLHttpRequest和DOM。XMLHttpRequest是ajax的核心机制

XMLHttpRequest(XHR)对象用于与服务器交互。通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL,获取数据。这允许网页在不影响用户操作的情况下,更新页面的局部内容。XMLHttpRequest 可以用于获取任何类型的数据,而不仅仅是 XML。甚至支持 HTTP以外的协议(包括 file:// 和 FTP),尽管可能受到更多出于安全等原因的限制。

/** 1. 创建Ajax对象 **/
var xhr = window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject('Microsoft.XMLHTTP');// 兼容IE6及以下版本
/** 2. 配置 Ajax请求 **/
xhr.open('get', url, true)
/** 3. 发送请求 **/
xhr.send(null); // 严谨写法
/** 4. 监听请求,接受响应 **/
xhr.onreadystatechange = function(){
    if(xhr.readyState == 4){
        if(xhr.status == 200){
            success(xhr.responseText);
        } else { 
            /** false **/
            fail && fail(xhr.status);
        }
    }
}
  • onreadystatechange:当 readyState 属性发生变化时,调用的事件处理函数

  • readyState:

    状态 描述
    0 UNSENT 代理被创建,但尚未调用 open() 方法。
    1 OPENED open() 方法已经被调用。
    2 HEADERS_RECEIVED send() 方法已经被调用,并且头部和状态已经可获得。
    3 LOADING 下载中; responseText 属性已经包含部分数据。
    4 DONE 下载操作已完成。
  • response:返回的包含整个响应实体

  • responseText:返回一个DOMString,该 DOMString 包含对请求的响应,如果请求未成功或尚未发送,则返回 null。

  • responseType:一个用于定义响应类型的枚举值(enumerated value)。

    类型 解释
    “ ” 空的 responseType 字符串与默认类型 "text" 相同。
    "arraybuffer" response 是一个包含二进制数据的 JavaScript ArrayBuffer
    "blob" response 是一个包含二进制数据的 Blob 对象。
    "document" response 是一个 HTMLDocument或XMLDocument
    "json" response是通过将接收到的数据内容解析为JSON的JS对象
    "text" response 是 DOMString 对象中的文本。
    "ms-stream" response是流式下载的一部分;此响应类型仅允许用于下载请求,并且仅受 Internet Explorer 支持。
  • status:返回一个无符号短整型(unsigned short)数字,代表请求的响应状态。

    var xhr = new XMLHttpRequest();
    console.log('UNSENT', xhr.status);
    
    xhr.open('GET', '/server', true);
    console.log('OPENED', xhr.status);
    
    xhr.onprogress = function () {
      console.log('LOADING', xhr.status);
    };
    
    xhr.onload = function () {
      console.log('DONE', xhr.status);
    };
    
    xhr.send(null);
    
    /**
     * 输出如下:
     *
     * UNSENT(未发送) 0
     * OPENED(已打开) 0
     * LOADING(载入中) 200
     * DONE(完成) 200
     */
  • withCredentials:一个布尔值,用来指定跨域 Access-Control 请求是否应当带有授权信息,如 cookie 或授权 header 头。xhr.withCredentials=true

  • upload:代表上传进度

其他更多XMLHttpRequest相关api

ajax 有那些优缺点?

  • 优点:

    • 通过异步模式,提升了用户体验.
    • 优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用.
    • Ajax在客户端运行,承担了一部分本来由服务器承担的工作,减少了大用户量下的服务器负载。
    • Ajax可以实现动态不刷新(局部刷新)
  • 缺点:

    • 安全问题 AJAX暴露了与服务器交互的细节。
    • 对搜索引擎的支持比较弱。
    • 不容易调试。

Promise封装Ajax

promise 封装实现:

// promise 封装实现:
function getJSON(url) {
  // 创建一个 promise 对象
  let promise = new Promise(function(resolve, reject) {
    let xhr = new XMLHttpRequest();

    // 新建一个 http 请求
    xhr.open("GET", url, true);

    // 设置状态的监听函数
    xhr.onreadystatechange = function() {
      if (this.readyState !== 4) return;

      // 当请求成功或失败时,改变 promise 的状态
      if (this.status === 200) {
        resolve(this.response);
      } else {
        reject(new Error(this.statusText));
      }
    };

    // 设置错误监听函数
    xhr.onerror = function() {
      reject(new Error(this.statusText));
    };

    // 设置响应的数据类型
    xhr.responseType = "json";

    // 设置请求头信息
    xhr.setRequestHeader("Accept", "application/json");

    // 发送 http 请求
    xhr.send(null);
  });
  return promise;
}

JQ Ajax、Axios、Fetch的核心区别

JQuery Ajax

Ajax前后端数据通信「同源、跨域」

// 用户登录 -> 登录成功 -> 获取用户信息
/* 回调地狱 */
$.ajax({
    url: 'http://127.0.0.1:8888/user/login',
    method: 'post',
    data: Qs.stringify({
        account: '18310612838',
        password: md5('1234567890')
    }),
    success(result) {
        if (result.code === 0) {
            // 登录成功
            $.ajax({
                url: 'http://127.0.0.1:8888/user/list',
                method: 'get',
                success(result) {
                    console.log(result);
                }
            });
        }
    }
});

优缺点:

  • 本身是针对MVC的编程,不符合现在前端MVVM的浪潮
  • 基于原生的XHR开发,XHR本身的架构不清晰,已经有了fetch的替代方案
  • JQuery整个项目太大,单纯使用ajax却要引入整个JQuery非常的不合理(采取个性化打包的方案又不能享受CDN服务)

Axios

Axios也是对ajax的封装,基于Promise管理请求,解决回调地狱问题

axios({
    method: 'post',
    url: '/user/login',
    data: {
        username: 'name',
        password: 'password'
    }
})
.then(function (response) {
    console.log(response);
})
.catch(function (error) {
    console.log(error);
});
// 或使用 async await
(async function () {
    let result1 = await axios.post('/user/login', {
        username: 'name',
        password: 'password'
    });
    let result2 = await axios.get('/user/list');
    console.log(result1, result2);
})();

优缺点:

  • 从浏览器中创建 XMLHttpRequest
  • 从 node.js 发出 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求和响应数据
  • 取消请求
  • 自动转换JSON数据
  • 客户端支持防止CSRF/XSRF

Fetch

Fetch是ES6新增的通信方法,不是ajax,但是他本身实现数据通信,就是基于promise管理的

try {
  let response = await fetch(url, options);
  let data = response.json();
  console.log(data);
} catch(e) {
  console.log("Oops, error", e);
}

示例:

(async function () {
    let result = await fetch('http://127.0.0.1:8888/user/login', {
        method: 'post',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: Qs.stringify({
            name: 'name',
            password: 'password'
        })
    })
    let data = result.json();
    console.log(data)
​
    let result2 = await fetch('http://127.0.0.1:8888/user/list').then(response => {
        return response.json();
    });
    console.log(result2);
})();

优缺点:

  • fetcht只对网络请求报错,对400,500都当做成功的请求,需要封装去处理
  • fetch默认不会带cookie,需要添加配置项
  • fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了量的浪费
  • fetch没有办法原生监测请求的进度,而XHR可以

补充:为什么要用axios?

axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,它本身具有以下特征:

  • 从浏览器中创建 XMLHttpRequest
  • 从 node.js 发出 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求和响应数据
  • 取消请求
  • 自动转换JSON数据
  • 客户端支持防止CSRF/XSRF
  • axios既提供了并发的封装,也没有fetch的各种问题,而且体积也较小,当之无愧现在最应该选用的请求的方式。

三选一绝必是axios了。其流程图如下:

AJAX引擎原理以及XmlHttpRequest对象的axios、fetch区别详解

总结

到此这篇关于AJAX原理以及axios、fetch区别的文章就介绍到这了,更多相关AJAX原理 axios、fetch区别内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
jquery 自定义容器下雨效果可将下雨图标改为其他
Apr 23 Javascript
javascript arguments使用示例
Dec 16 Javascript
javascript实现简单的全选和反选功能
Jan 05 Javascript
快速解决jquery.touchSwipe左右滑动和垂直滚动条冲突
Apr 15 Javascript
微信小程序 for 循环详解
Oct 09 Javascript
vue实现ajax滚动下拉加载,同时具有loading效果(推荐)
Jan 11 Javascript
在layui下对元素进行事件绑定的实例
Sep 06 Javascript
three.js利用gpu选取物体并计算交点位置的方法示例
Nov 25 Javascript
JS模拟实现京东快递单号查询
Nov 30 Javascript
用Javascript实现发送短信验证码间隔功能
Feb 08 Javascript
详解TypeScript中的类型保护
Apr 29 Javascript
JavaScript组合继承详解
Nov 07 Javascript
vue如何实现关闭对话框后刷新列表
Apr 08 #Vue.js
vue实现列表垂直无缝滚动
Apr 08 #Vue.js
vue3引入highlight.js进行代码高亮的方法实例
vue中的可拖拽宽度div的实现示例
vue 实现弹窗关闭后刷新效果
Apr 08 #Vue.js
vue中this.$http.post()跨域和请求参数丢失的解决
Apr 08 #Vue.js
vue实现书本翻页动画效果实例详解
Apr 08 #Vue.js
You might like
支持oicq头像的留言簿(二)
2006/10/09 PHP
写php分页时出现的Fatal error的解决方法
2011/04/18 PHP
解析PHP中一些可能会被忽略的问题
2013/06/21 PHP
PHP中字符安全过滤函数使用小结
2015/02/25 PHP
PHP版本如何选择?应该使用哪个版本?
2015/05/13 PHP
php统计数组元素个数的方法
2015/07/02 PHP
PHP浮点比较大小的方法
2016/02/14 PHP
php fread函数使用方法总结
2019/05/28 PHP
PHPStorm 2020.1 调试 Nodejs的多种方法详解
2020/09/17 NodeJs
JQuery 构建客户/服务分离的链接模型中Table分页代码效率初探
2010/01/22 Javascript
使用GruntJS构建Web程序之构建篇
2014/06/04 Javascript
JS替换字符串中字符即替换全部而不是第一个
2014/06/04 Javascript
一个JavaScript防止表单重复提交的实例
2014/10/21 Javascript
详解jquery中$.ajax方法提交表单
2014/11/03 Javascript
javascript定义变量时带var与不带var的区别分析
2015/01/12 Javascript
动态的9*9乘法表效果的实现代码
2016/05/16 Javascript
jQuery实现6位数字密码输入框
2016/12/29 Javascript
BootStrap Datetimepicker 汉化的实现代码
2017/02/10 Javascript
js+canvas实现验证码功能
2020/09/21 Javascript
vue router 跳转后回到顶部的实例
2018/08/31 Javascript
angular使用md5,CryptoJS des加密的方法
2019/06/03 Javascript
tracking.js实现前端人脸识别功能
2020/04/16 Javascript
Python实现在线程里运行scrapy的方法
2015/04/07 Python
用tensorflow搭建CNN的方法
2018/03/05 Python
在Python 中同一个类两个函数间变量的调用方法
2019/01/31 Python
使用Python3内置文档高效学习以及官方中文文档
2019/05/19 Python
python文件操作的简单方法总结
2019/11/07 Python
阿迪达斯芬兰官方网站:adidas芬兰
2017/01/30 全球购物
匡威西班牙官网:Converse西班牙
2019/10/01 全球购物
上班离岗检讨书
2014/01/27 职场文书
工程类专业自荐信范文
2014/03/09 职场文书
民主评议党员自我鉴定
2014/10/21 职场文书
教师党员个人总结
2015/02/10 职场文书
解决Jenkins集成SonarQube遇到的报错问题
2021/07/15 Java/Android
MySQL 中如何归档数据的实现方法
2022/03/16 SQL Server
忘记Grafana不要紧2种Grafana重置admin密码方法详细步骤
2022/04/07 Servers