目录
  • AJAX原理
  • Promise封装Ajax
  • JQ Ajax、Axios、Fetch的核心区别
    • JQuery Ajax
    • Axios
    • Fetch
  • 补充:为什么要用axios?
    • 总结

      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原理以及axios、fetch区别实例详解

      总结

      声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。