zoukankan      html  css  js  c++  java
  • 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();
    }
    
    优秀文章首发于聚享小站,欢迎关注!
  • 相关阅读:
    SuperMap房产测绘成果管理平台
    SuperMap产权登记管理平台
    Android adb shell am 的用法(1)
    由浅入深谈Perl中的排序
    Android 内存监测和分析工具
    Android 网络通信
    adb server is out of date. killing...
    引导页使用ViewPager遇到OutofMemoryError的解决方案
    adb logcat 详解
    How to send mail by java mail in Android uiautomator testing?
  • 原文地址:https://www.cnblogs.com/yesyes/p/15352613.html
Copyright © 2011-2022 走看看