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 相关文章推荐
Javascript操纵Cookie实现购物车程序
Feb 15 Javascript
javascript 45种缓动效果 非常酷
Jun 28 Javascript
js判断上传文件类型判断FileUpload文件类型代码
May 20 Javascript
js+html5绘制图片到canvas的方法
Jun 05 Javascript
深入理解JavaScript的React框架的原理
Jul 02 Javascript
原生js模拟淘宝购物车项目实战
Nov 18 Javascript
JS给Array添加是否包含字符串的简单方法
Oct 29 Javascript
详解Angular的内置过滤器和自定义过滤器【推荐】
Dec 26 Javascript
js实现手机web图片左右滑动效果
Dec 29 Javascript
浅析微信扫码登录原理(小结)
Oct 29 Javascript
vue cli使用融云实现聊天功能的实例代码
Apr 19 Javascript
Web应用开发TypeScript使用详解
May 25 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
详谈PHP文件目录基础操作
2014/11/11 PHP
PHP将页面中点击数量高的链接进行高亮显示的方法
2016/05/30 PHP
PHP文件操作实例总结【文件上传、下载、分页】
2018/12/08 PHP
php使用curl伪造浏览器访问操作示例
2019/09/30 PHP
js封装的textarea操作方法集合(兼容很好)
2010/11/16 Javascript
ExtJS4 组件化编程,动态加载,面向对象,Direct
2011/05/12 Javascript
Javascript 类、命名空间、代码组织代码
2011/07/31 Javascript
拥抱模块化的JavaScript
2012/03/07 Javascript
用jQuery与JSONP轻松解决跨域访问的问题
2014/02/04 Javascript
checkbox选中与未选中判断示例
2014/08/04 Javascript
jquery实现textarea 高度自适应
2015/03/11 Javascript
jQuery实现鼠标滑向当前图片高亮显示并且其它图片变灰的方法
2015/07/27 Javascript
JavaScript实现身份证验证代码
2016/02/17 Javascript
限制文本框只能输入数字||只能是数字和小数点||只能是整数和浮点数
2016/05/27 Javascript
jquery获取easyui日期控件的值实现方法
2016/11/09 Javascript
js轮播图无缝滚动效果
2017/06/17 Javascript
vue实现一拉到底的滑动验证
2019/07/25 Javascript
Nodejs使用archiver-zip-encrypted库加密压缩文件时报错(解决方案)
2019/11/18 NodeJs
vue 动态创建组件的两种方法
2020/12/31 Vue.js
[02:09:59]火猫TV国士无双dota2 6.82版本详解(下)
2014/09/29 DOTA
Python、Javascript中的闭包比较
2015/02/04 Python
Python3中的最大整数和最大浮点数实例
2019/07/09 Python
Python集合基本概念与相关操作实例分析
2019/10/30 Python
tornado+celery的简单使用详解
2019/12/21 Python
python如何设置静态变量
2020/09/07 Python
Python gevent协程切换实现详解
2020/09/14 Python
python 实现非极大值抑制算法(Non-maximum suppression, NMS)
2020/10/15 Python
荷兰时尚精品店:Labels Fashion
2020/03/22 全球购物
优秀教师主要事迹
2014/02/01 职场文书
个人自我剖析材料
2014/09/30 职场文书
小学教师先进事迹材料
2014/12/15 职场文书
质检员岗位职责
2015/02/03 职场文书
环保主题班会教案
2015/08/13 职场文书
基于python制作简易版学生信息管理系统
2021/04/20 Python
vue3 自定义图片放大器效果的示例代码
2022/07/23 Vue.js
MySQL索引失效十种场景与优化方案
2023/05/08 MySQL