前面的話
1999年,微軟公司發布IE5,第一次引入新功能:允許javascript腳本向伺服器發起HTTP請求。這個功能當時並沒有引起注意,直到2004年Gmail發布和2005年Google Map發布,才引起廣泛重視。 2005年2月,ajax這個詞第一次正式提出,指圍繞這個功能進行開發的一整套做法。從此,ajax成為腳本發起HTTP通訊的代名詞,W3C也在2006年發布了它的國際標準。本文是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'); }
xhr.open("get","example.php", false);
[注意]如果要建立N個不同的請求,就要使用N個不同的XHR物件。當然可以重複使用已存在的XHR對象,但這會終止先前透過該物件掛起的任何請求
發送請求
open()在使用XHR物件時,要呼叫的第一個方法是open(),如下所示,該方法接受3個參數
xhr.open("get", "example.txt", false); xhr.send(null);
1、 open()方法的第一個參數用來指定發送請求的方式,這個字串,不區分大小寫,但通常使用大寫字母。 "GET"和"POST"是廣泛支援的
"GET"用於常規請求,它適用於當URL完全指定請求資源,當請求對伺服器沒有任何副作用以及當伺服器的回應是可快取的情況下
"POST"方法常用於HTML表單。它在請求主體中包含額外資料且這些資料常儲存到伺服器上的資料庫中。相同URL的重複POST請求從伺服器得到的回應可能不同,同時不應該快取使用這個方法的請求
# 除了"GET"和"POST"之外,參數還可以是"HEAD"、"OPTIONS "、"PUT"。而由於安全風險的原因,"CONNECT"、"TRACE"、"TRACK"被禁止使用# [注意]關於HTTP協議8種常用方法的詳細介紹移步至此
2 、open()方法的第二個參數是URL,該URL相對於執行程式碼的目前頁面,且只能向同一個網域中使用相同連接埠和協定的URL傳送請求。如果URL與啟動請求的頁面有任何差別,都會引發安全錯誤
3、open()方法的第三個參數是表示是否非同步傳送請求的布林值,如果不填寫,預設為true,表示非同步發送
send()方法接收一個參數,也就是要作為請求主體傳送的資料。呼叫send()方法後,請求被分派到伺服器
responseText: 作为响应主体被返回的文本(文本形式) responseXML: 如果响应的内容类型是'text/xml'或'application/xml',这个属性中将保存着响应数据的XML DOM文档(document形式) status: HTTP状态码(数字形式) statusText: HTTP状态说明(文本形式)
if((xhr.status >=200 && xhr.status ###<p> 在接收到响应后,第一步是检查status属性,以确定响应已经成功返回。一般来说,可以将HTTP状态码为200作为成功的标志。此时,responseText属性的内容已经就绪,而且在内容类型正确的情况下,responseXML也可以访问了。此外,状态码为304表示请求的资源并没有被修改,可以直接使用浏览器中缓存的版本;当然,也意味着响应是有效的</p><p> 无论内容类型是什么,响应主体的内容都会保存到responseText属性中,而对于非XML数据而言,responseXML属性的值将为null</p><div class="cnblogs_code"><pre class="brush:php;toolbar:false">if((xhr.status >=200 && xhr.status
如果接受的是同步响应,则需要将open()方法的第三个参数设置为false,那么send()方法将阻塞直到请求完成。一旦send()返回,仅需要检查XHR对象的status和responseText属性即可
同步请求是吸引人的,但应该避免使用它们。客户端javascript是单线程的,当send()方法阻塞时,它通常会导致整个浏览器UI冻结。如果连接的服务器响应慢,那么用户的浏览器将冻结
<button>获取信息</button> <div></div> <script> btn.onclick = function(){ //创建xhr对象 var xhr; if(window.XMLHttpRequest){ xhr = new XMLHttpRequest(); }else{ xhr = new ActiveXObject('Microsoft.XMLHTTP'); } //发送请求 xhr.open('get','/uploads/rs/26/ddzmgynp/message.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的阶段感兴趣,因为这时所有数据都已就绪
[注意]必须在调用open()之前指定onreadystatechange 事件处理程序才能确保跨浏览器兼容性,否则将无法接收readyState属性为0和1的情况
xhr.onreadystatechange = function(){ if(xhr.readyState === 4){ if(xhr.status == 200){ alert(xhr.responseText); } } }
<button>获取信息</button> <div></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>
//message.xml <p>hello world</p>
XHR对象的timeout属性等于一个整数,表示多少毫秒后,如果请求仍然没有得到结果,就会自动终止。该属性默认等于0,表示没有时间限制
如果请求超时,将触发ontimeout事件
[注意]IE8-浏览器不支持该属性
xhr.open('post','test.php',true); xhr.ontimeout = function(){ console.log('The request timed out.'); } xhr.timeout = 1000; xhr.send();
使用AJAX接收数据时,由于网络和数据大小的原因,并不是立刻就可以在页面中显示出来。所以,更好的做法是,在接受数据的过程中,显示一个类似loading的小图片,并且禁用按钮;当数据完全接收后,再隐藏该图片,并启用按钮
<button>获取信息</button> <img alt="ajax系列之XHR對象的理解" > <div></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]); ?>
最後
透過實例的示範發現,ajax前端本身的內容並不難。但是,由於ajax涉及一些後端及網絡的知識,使得學起來不是很容易。以後的部落格文章將逐步深入介紹ajax的重點內容
以上是ajax系列之XHR對象的理解的詳細內容。更多資訊請關注PHP中文網其他相關文章!