• JS之AJAXXHR对象


    AJAX是Asynchronous JavasSript And XML的简写,这项技术能够在不卸载页面的情况下发出HTTP请求,虽然名字中包含XML,但AJAX通信与数据格式无关

    AJAX通信通常包含4个步骤:

    1. 创建XMLHttpRequest对象
    2. 发送HTTP请求
    3. 接收服务器返回的数据
    4. 更新网页数据

    创建

    AJAX技术的核心是XMLHttpRequest对象(简称XHR),可以直接使用new关键字实例化一个XHR对象

    var xhr = new XMLHttpRequest()
    

    注意: 如果要建立N个不同的请求,理论上需要使用N个不同的XHR对象。如果重用已存在的XHR对象,会终止之前通过该对象挂起的任何请求

    发送请求

    open()

    XHR对象的open()方法用于发送请求,该方法接收三个参数:请求方式、请求地址和一个布尔值

    xhr.open("GET","/api/test", true);
    

    请求方式:请求方式比较常用的是GET和POST,也可以是PATCH、DELETE、OPTIONS等。这个字符串是不区分大小写的,但通常使用大写字母。

    请求地址:请求地址通常是相对于执行代码的当前页面。如果需要发出跨域请求,后端要支持CORS,否则会报错

    布尔值:布尔值表示是否异步发送请求的布尔值,默认为true,表示异步发送

    其他:如果请求一个受密码保护的URL,可以把用于认证的用户名和密码作为第4和第5个参数传递给open()方法

    send()

    open()方法调用后,必须执行send()方法才会真正发送请求。如果是GET方式,send()方法无参数,或参数为null;如果是POST方式,send()方法的参数为要发送的数据

    xhr.open('GET', 'https://www.86886.wang/api/tags', true); 
    xhr.send(null);
    

    接收响应

    一个完整的HTTP请求由响应状态码、响应头集合和响应主体组成。在收到响应后,这些都可以通过XHR对象的属性和方法使用,主要有以下4个属性

    responseText:    作为响应主体被返回的文本(文本形式)
    responseXML:     如果响应的内容类型是'text/xml'或'application/xml',这个属性中将保存着响应数据的XML DOM文档(document形式)
    status:          HTTP状态码(数字形式),比如200
    statusText:      HTTP状态说明(文本形式),比如OK
    

    在接收到响应后,第一步是检测status状态,HTTP状态码为200表示请求成功,此时responseText属性的内容已经就绪。另外状态码304表示资源没有被修改,可以直接从浏览器缓存获取,这个响应也是有效的

    无论内容类型是什么,响应主体的内容都会保存到responseText属性中。对于非XML数据而言(如JSON),responseXML属性的值将为null

    if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
      console.log(xhr.responseText);
    }else{
      console.log('Request fail:' + xhr.status);
    }
    

    同步请求

    把open()方法的第三个参数设置为false,表示是同步请求,此时send()方法将会阻塞直到请求完成。由于JS是单线程的,所以会导致整个浏览器UI冻结,如果连接的服务器响应慢,那么用户的浏览器将冻结

    开发中要避免使用同步请求,下面是同步请求的示例

    <div id="result"></div>
    <button id="btn">GET同步请求</button>
    <script>
      btn.onclick = function() {
        var data = ajax();
        result.innerHTML = data;
      }
      function ajax() {
        var xhr = new XMLHttpRequest();
        if(xhr.readyState == 4) {
          if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
            return xhr.responseText;
          }
        }
        // 同步请求
        xhr.open('GET', 'https://www.86886.wang/api/tags', false);
        xhr.send();
      }
    </script>
    

    异步请求

    异步请求需要检测XHR对象的readyState属性,该属性表示请求/响应过程的当前活动阶段,取值如下:

    0(UNSENT):未初始化。尚未调用open()方法
    1(OPENED):启动。已经调用open()方法,但尚未调用send()方法
    2(HEADERS_RECEIVED):发送。己经调用send()方法,且接收到头信息
    3(LOADING):接收。已经接收到部分响应主体信息
    4(DONE):完成。已经接收到全部响应数据,而且已经可以在客户端使用了
    

    只要readyState属性值发生变化,就会触发onreadystatechange事件,通常只需要对值为4时做判断,此时表示数据已经准备就绪

    注意: 必须在调用open()之前指定onreadystatechange 事件处理程序才能确保跨浏览器兼容性,否则将无法接收readyState属性为0和1的情况

    异步请求示例

    <div id="result"></div>
    <button id="btn">GET异步请求</button>
    <script>
      btn.onclick = function() {
        ajax(function(data) {
          result.innerHTML = data;
        });
      }
      function ajax(cb) {
        var xhr = new XMLHttpRequest();
        // 异步请求
        xhr.onreadystatechange = function() {
          if(xhr.readyState == 4) {
            if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
              cb(xhr.responseText);
            }
          }
        }
        xhr.open('GET', 'https://www.86886.wang/api/tags', true);
        xhr.send();
      }
    </script>
    

    超时

    XHR对象有一个timeout属性,表示多少毫秒后,如果请求仍然没有得到结果就会自动终止。默认值0,表示没有限制

    如果请求超时,会触发ontimeout事件

    function ajax(cb) {
      var xhr = new XMLHttpRequest();
      // 异步请求
      xhr.onreadystatechange = function() {
        if(xhr.readyState == 4) {
          if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
            cb(xhr.responseText);
          }
        }
      }
      xhr.open('GET', 'https://www.86886.wang/api/tags', true);
      xhr.ontimeout = function() {
        console.log('The request timed out.');
      }
      xhr.timeout = 5000; // 5s
      xhr.send();
    }
    
    优秀文章首发于聚享小站,欢迎关注!
  • 相关阅读:
    数据科学 R语言速成
    F#周报2019年第29期
    F#周报2019年第28期
    F#周报2019年第27期
    F#周报2019年第26期
    F#周报2019年第25期
    F#周报2019年第24期
    F#周报2019年第23期
    .NET工程师的书单
    F#周报2019年第22期
  • 原文地址:https://www.cnblogs.com/yesyes/p/15352613.html
Copyright © 2020-2023  润新知