深入理解ajax系列之一-XHR对象

概述

  ajax是asynchronous javascript and XML的简写,中文翻译是异步的javascript和XML,这一技术能够向服务器请求额外的数据而无须卸载页面,会带来更好的用户体验。虽然名字中包含XML,但ajax通信与数据格式无关。

ajax包括几个步骤:

1:创建ajax请求,
2:发出http请求
3:收到服务器传回的消息
4:更新网页数据、

  概括起来,就是一句话,ajax通过原生的XMLHttpRequest对象发出HTTP请求,得到服务器返回的数据后,再进行处理。

创建

 ajax技术的核心是XMLHttpRequest对象(简称XHR),这是由微软首先引入的一个特性,其他浏览器提供商后来都提供了相同的实现。XHR为向服务器发送请求和解析服务器响应提供了流畅的接口,能够以异步方式从服务器取得更多信息,意味着用户单击后,可以不必刷新页面也能取得新数据

  IE5是第一款引入XHR对象的浏览器。在IE5中,XHR对象是通过MSXML库中的一个ActiveX对象实现的,而IE7+及其他标准浏览器都支持原生的XHR对象

  创建一个XHR对象,也叫实例化一个XHR对象,因为XMLHTTPRequest()是一个构造函数。下面是创建XHR对象的兼容写法

var xhr;
if(window.XMLHttpRequest){
    xhr = new XMLHttpRequest();
}else{
    xhr = new ActiveXObject('Microsoft.XMLHTTP');
}

  [注意]如果要建立N个不同的请求,就要使用N个不同的XHR对象。当然可以重用已存在的XHR对象,但这会终止之前通过该对象挂起的任何请求。

发动请求

open();

在使用xrh的时候第一个调用的是open方法,如下,该方法接受3个参数,

xrh.open('GET','example.php',false);
  1. open()方法的第一个参数用于指定发送请求的方式,这个字符串,不区分大小写,但通常使用大写字母。”GET”和”POST”是得到广泛支持的.

    ‘GET’用于常规请求,它适用于URL完全指定的资源。当请求对服务器没有任何副作用是可缓存的情况下,

‘POST’方法常用与HTML表单,他在请求主题中额外包含数据且这些数据常存在服务器上的数据库中。相同的URL的重复POST请求从服务器的得到的相应可能不同

  除了”GET”和”POST”之外,参数还可以是”HEAD”、”OPTIONS”、”PUT”。而由于安全风险的原因,”CONNECT”、”TRACE”、”TRACK”被禁止使用.

2. open()的第二个参数是URL,该URL对于执行代码的当前页面,且只能想同一域中使用相同协议和端口的URL发送请求。

3.open()的第三个参数是表示是否异步发送请求的值,如果不填写。默认身高true,表示异步发送,

4.如果请求一个手密码保护的URL用于认证的用户和密码作为第4和第5个参数传递给open()方法。

send()

send()方法接受一个参数,即作为请求主题发送的数据。调用send()方法后,请求被分配到服务器。

如果是GET方法,send()方法无参数,或参数为null;如果是POST方法,send()方法的参数是要发送的的数据。

xhr.open("GET","xxx.php",true)
xhr.send(null);

接受响应

一个完整的http响应是有状态吗,响应头集合,和响应主题组成。在收到响应的消息后,这些都是可以通过xhr对象的属性个方法所使用,主要有一下4个属性

responseText;作为相应主题返回的文本,(文本形式)
responseXML;如果响应的内容是‘text/xml’或者是哦application/xml;属性中将会保存,响应数据的xml形式。DOM文档形式。

status: http的状态码(数字形式)
statusText;http状态说明,(文本形式)

收到响应后,第一步是检查status,以确定响应已经成功的返回,一般来说。http状态码200作为成功的标志。此时,responseText属性的内容也已经准备就绪,而且在内容正确的情况下,responseText的内容也可以访问了,此外状态码304表示资源并没有被修改,可以直接使用浏览器中的缓存。

无论响应内容是什么类型。都会被保存在responseText中,而对于非XML数据而言,responseText的值则为null;

  除了"GET""POST"之外,参数还可以是"HEAD""OPTIONS""PUT"。而由于安全风险的原因,"CONNECT""TRACE""TRACK"被禁止使用

同步

如果接受的是同步响应,在在open()方法的第三个参数设置为false,那么send()方法将阻塞,直到请求完成,一旦send()返回,仅需检查XHR对象的responseText属性和status即可。
  同步请求是吸引人的,但应该避免使用它们。客户端javascript是单线程的,当send()方法阻塞时,它通常会导致整个浏览器UI冻结。如果连接的服务器响应慢,那么用户的浏览器将冻结

<button id="btn">点击</button>
<div id=result></div>
<script>
  btn.onclick=function(){
    var xhr;
    if(window.XMLHttpRequst){
     var xhr = window.XMLHttpRequst;
   }else {
    xhr = new ActiveXObject('Microsoft.XMLHTTP');
   }
   //发送请求
   xhr.open("GET","xx.xml",false);
   xhr.send();
   //同步接受响应
   if(xhr.readyState==4){
     if(xhr.status == 200){
        result.innerHTML += xhr.responseText;
     }
   }

} 

</script>
//message.xml
<p>hello world</p>

异步

如果接受的异步响应,这就需要检测XHR的readyState的属性,该属性表示,请求/响应过程中当前的活动阶段,这个属性可以去一下的值,

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

理论上,只要readyState属性的值由一个值变为另一个值,就会出发一次readyStatechange事件,可以利用这个事件来检测每次状态变化的readyState的值,我们对readyState值为4的阶段感兴趣,因为这时所有数据都已就绪,

<button id="btn">获取信息</button>
<div id="result"></div>
<script>
btn.onclick = function(){
    //创建xhr对象
    var xhr;
    if(window.XMLHttpRequest){
        xhr = new XMLHttpRequest();
    }else{
        xhr = new ActiveXObject('Microsoft.XMLHTTP');
    }
    //异步接受响应
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){
            if(xhr.status == 200){
                //实际操作
                result.innerHTML += xhr.responseText;
            }
        }
    }
    //发送请求
    xhr.open('get','message.xml',true);
    xhr.send();
}
</script> 

超时


xhr.open("GET","xxx.php",true);
xhr.ontimeout=function(){
    console.log("请求超市")
}
xhr.timeout = 1000;
xhr.send();

优化

  使用AJAX接收数据时,由于网络和数据大小的原因,并不是立刻就可以在页面中显示出来。所以,更好的做法是,在接受数据的过程中,显示一个类似loading的小图片,并且禁用按钮;当数据完全接收后,再隐藏该图片,并启用按钮。

<button id="btn">获取信息</button>
<img id="img" height="16" style="display:none" src="data:image/gif;base64,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" alt="loading">
<div id="result"></div>

<script>
var add = (function(){
    var counter = 0;
    return function(){
        return ++counter;
    }
})();
btn.onclick = function(){
    img.style.display = 'inline-block';
    btn.setAttribute('disabled','');
    //创建xhr对象
    var xhr;
    if(window.XMLHttpRequest){
        xhr = new XMLHttpRequest();
    }else{
        xhr = new ActiveXObject('Microsoft.XMLHTTP');
    }
    //异步接受响应
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){
            if(xhr.status == 200){
              img.style.display = 'none';
              btn.removeAttribute('disabled');
              var data = JSON.parse(xhr.responseText);
              var sum = add() - 1;
              if(sum < data.length){
                result.innerHTML += data[sum];    
              }
            }
        }
    }
    //发送请求
    xhr.open('get','data.php',true);
    xhr.send();
}
</script>      
<?php
echo json_encode([1,2,3,4,5]);
?>

猜你喜欢

转载自blog.csdn.net/arthurwanggang/article/details/68938511
今日推荐