Ajax基礎詳解教程(二)
在上篇文章給大家介紹了Ajax基礎詳解教程(一),講到Ajax中open方法的第三個參數(shù)異步和同步的問題,今天呢,就來繼續(xù)往下嘮,先接著上回的代碼
var oBtn = document.getElementById('btn'); oBtn.onclick = function(){ var xhr = null; if(window.XMLHttpRequest){ xhr = new XMLHttpRequest(); }else{ xhr = new ActiveXObject(‘Microsoft.XMLHTTP'); } xhr.open('get','1.txt',true); //設置請求信息 xhr.send();//提交請求 //等待服務器返回內(nèi)容 xhr.onreadystatechange = function() { if ( xhr.readyState == 4 ) { //如果內(nèi)容響應成功,并解析完成 alert( xhr.responseText ); //彈出內(nèi)容 } } }
下面我們就講到 ,xhr.send();這一句呢才是真正請求數(shù)據(jù)的,open方法只是設置了一些請求參數(shù)。
現(xiàn)在呢請求遞交了,就等服務器回應了,這個時候Ajax的一個屬性就要登場了,那就是 responseText ,ajax請求返回的內(nèi)容都放在了這里面,而且不管你請求的內(nèi)容是什么,這里存放的都是是字符串類型。
當然我們上文也提到了,要想用異步請求呢,這里需要條件判斷才知道服務端對請求的內(nèi)容是否響應完畢,這個時候另一個屬性就要登場了,readyState,他代表著Ajax請求過程的不同的狀態(tài),參數(shù)如下:
0 (初始化)還沒有調(diào)用open()方法
1 (載入)已調(diào)用send()方法,正在發(fā)送請求
2 (載入完成)send()方法完成,已收到全部響應內(nèi)容
3 (解析)正在解析響應內(nèi)容(因為收到的內(nèi)容 并不是人能看懂的內(nèi)容,所以需要解析)
4 (完成)響應內(nèi)容解析完成,可以在客戶端調(diào)用了
由上我們可以得到,在狀態(tài)2的時候已經(jīng)回應了請求的內(nèi)容了,但是這個內(nèi)容我們?nèi)丝床欢?,機器才懂,所以就有3,幫我們解析這個內(nèi)容,然后解析完成就變成4了,這個時候的內(nèi)容,咱們前端就可以用了。
狀態(tài)是有了,可咱們怎么能知道啥時候是啥狀態(tài)呢,這個時候我們就要用到一個監(jiān)控狀態(tài)的事件了onreadystatechange事件,當狀態(tài)值改變的時候觸發(fā)會觸發(fā)這個事件,所以當狀態(tài)為4的時候我們再彈出內(nèi)容。
上面的代碼基本已經(jīng)了解了原理,不過當然不是最完善的,這個時候,我們雖然監(jiān)控到了狀態(tài),響應了內(nèi)容,但是內(nèi)容不一定就是對的呀,比如可能內(nèi)容出錯了,可能我們請求了一個不存在的頁面,這個時候readyState是無法判斷錯誤的,我們需要知道內(nèi)容是否正常,這個時候另一個屬性 status屬性就登場了,它代表的不是Ajax狀態(tài),而是服務器(請求資源)的狀態(tài), http狀態(tài)碼。狀態(tài)碼有很多,其中比較出名的就是200,成功狀態(tài)碼,和404 Not Found.其他的大家私下自行查閱。這里可以看到。
所以我們的代碼要做進一步的改進
var oBtn = document.getElementById('btn'); oBtn.onclick = function(){ var xhr = null; if(window.XMLHttpRequest){ xhr = new XMLHttpRequest(); }else{ xhr = new ActiveXObject('Microsoft.XMLHTTP'); } xhr.open('get','1.txt',true); //設置請求信息 xhr.send();//提交請求 //等待服務器返回內(nèi)容 xhr.onreadystatechange = function() { if ( xhr.readyState == 4 ) { if(xhr.status == 200) {//如果響應成功,并且服務器相應內(nèi)容正確 alert( xhr.responseText );//彈出內(nèi)容 }else{alert('出錯了' + xhr.status); //否則告知出錯并彈出錯誤原因 } } }
Ajax的大概流程就是這樣的。當然還存在一些細節(jié)方面的問題需要注意的,繼續(xù)往下看把。
工作當中 向后端傳遞數(shù)據(jù)存在的問題:
GET請求:
1 緩存問題:后臺更改了 因網(wǎng)址未變 所以會去緩存提取內(nèi)容 而不是后臺
來看個栗子:假如我們要點擊按鈕彈出名字和年齡,因為GET請求是通過數(shù)值串連然后在網(wǎng)址傳遞數(shù)據(jù)的,所以我們的open方法可以直接這樣寫:
xhr.open('get','1.get.php?username=沐晴&age=21',true);
后臺代碼不變
<?php header('content-type:text/html;charset="utf-8"'); //設置編碼格式,以及文檔類型 error_reporting(0); $username = $_GET['username'];//獲取get請求方式的數(shù)據(jù) $age = $_GET['age']; echo "你的名字:{$username},年齡:{$age}"; //輸出內(nèi)容
現(xiàn)在點擊肯定會彈出你的名字沐晴,年齡21 了。
這個時候呢,瀏覽器會有一個緩存,如果下次訪問相同的網(wǎng)址,就會從緩存里取。
比如我現(xiàn)在想彈出,歡迎你,你的名字沐晴,年齡21,
echo "歡迎,你的名字:{$username},年齡:{$age}"; //輸出內(nèi)容
雖然后臺代碼變了,但是GET請求訪問網(wǎng)址依然是 1.get.php?username=沐晴&age=21,所以后臺會去瀏覽器緩存找,結果彈出的還是原來的。大家可以自行測試。
所以,這個時候我們需要解決緩存問題。既然訪問網(wǎng)址不變的話會去找緩存,那么我們讓網(wǎng)址一直變不就好了。所以我們可以在后面加個一直變化的變量,比如系統(tǒng)事件,或者加一個隨機數(shù)都行,像下面這樣:
xhr.open('get','1.get.php?username=沐晴&age=21&'+new.Date.getTime(),true);
這樣就不會存在緩存問題了。有些人會這樣寫,會在后面給它起個名字t,這個時候如果后臺也有個變量叫t,可能就會出問題了,所以不是很推薦。
xhr.open('get','1.get.php?username=沐晴&age=21&t='+new.Date.getTime(),true);
post 請求
1 上節(jié)課我們知道,在表單里面?zhèn)鹘y(tǒng)方式POST請求的內(nèi)容是放在請求頭里的,那么Ajax是放在哪里的呢?
post 數(shù)據(jù)放在send里面作為參數(shù)傳遞。
2 還有一點是,我們上次我們知道表單里面的第三個參數(shù):enctype: 提交的數(shù)據(jù)格式,默認是application/x-www-form-urlencoded,但是在Ajax中,你不寫就沒有,沒有默認值,所以我們需要在請求頭里面指定提交的數(shù)據(jù)格式,不然瀏覽器不知道用哪種格式解析。
所以post請求需要設置下面這兩句
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded'); xhr.send('username=沐晴&age=21&');
無緩存問題,因為單單是往服務器提交數(shù)據(jù),提交數(shù)據(jù)是不會被緩存的,獲取數(shù)據(jù)才會被緩存。這就是web的機制。
前面講的都是請求數(shù)據(jù),現(xiàn)在來看一下后端接收請求,然后響應給我們的內(nèi)容。
先看看后端對數(shù)據(jù)的處理:后端的數(shù)據(jù)類型也是很多的,我們不能直接把這樣的數(shù)據(jù)給前端吧,所以后端也需要做一定的處理,它有個方法 json_encode 可以根據(jù)數(shù)據(jù)類型不同,然后輸出不同格式??聪旅娴睦踝?br />
<?php header('content-type:text/html;charset="utf-8"'); error_reporting(0); $arr1 = array('le','mo'); // 索引類型的數(shù)據(jù) $arr2 = array('username'=>'le','age'=>32); // 2 對應關系的數(shù)據(jù) echo json_encode($arr1); // ["le","mo"] 索引類型 輸出為數(shù)組格式 echo json_encode($arr2); // {"username":"le","age":32} 對應關系的數(shù)據(jù) 輸出為json格式
雖然后端輸出的內(nèi)容格式上是數(shù)組和json但是我之前提到過 alert( xhr.responseText );//這里彈出的可都是字符串類型,所以盡管格式上看著是json和數(shù)組,但實際的數(shù)據(jù)類型還是字符串。
所以我們前端要對這些字符串進行轉(zhuǎn)換。這個時候就用到了兩個方法
1 stringify() : 把json對象轉(zhuǎn)化成字符串 轉(zhuǎn)換后的字符串是嚴格的json格式
2 parse() : 把字符串轉(zhuǎn)成對象,可以把后端返回的字符串 轉(zhuǎn)成JSON格式,對于json,只能轉(zhuǎn)換嚴格json格式的字符串,字符串的鍵 比較用雙引號括起來 像這樣 {"username":"le","age":32}
下面來看個實際的案例:
需求:點擊頁面按鈕,實現(xiàn)頁面不刷新,在下面顯示新聞列表 看注釋應該能看懂
<!DOCTYPE HTML> <html> <head> <meta charset=utf-8"> <title>無標題文檔</title> <!--<script src="jquery.js"></script>--> <script> window.onload = function() { var oBtn = document.getElementById('btn'); oBtn.onclick = function() { var xhr = null; if(window.XMLHttpRequest){ xhr = new XMLHttpRequest(); }else{ xhr = new ActiveXObject('Microsoft.XMLHTTP'); } xhr.open('get','getNews.php',true); xhr.send(); xhr.onreadystatechange = function() { if ( xhr.readyState == 4 ) { if ( xhr.status == 200 ) { //alert( xhr.responseText ); 后端傳來的格式是一個數(shù)組里面很多條json 自己可以測試下 var data = JSON.parse( xhr.responseText ); // 將后臺獲取的內(nèi)容轉(zhuǎn)為json類型 每一個json里面有兩個鍵:title和date var oUl = document.getElementById('ul1'); //獲取顯示新聞列表的節(jié)點 var html = ''; for (var i=0; i<data.length; i++) { // 循環(huán)所有的json數(shù)據(jù),并把每一條添加到列表中 html += '<li><a href="">'+data[i].title+'</a> [<span>'+data[i].date+'</span>]</li>'; } oUl.innerHTML = html; //把內(nèi)容放在頁面里 } else { alert('出錯了,Err:' + xhr.status); } } } } } </script> </head> <body> <input type="button" value="按鈕" id="btn" /> <ul id="ul1"></ul> </body> </html> <?php header('content-type:text/html;charset="utf-8"'); error_reporting(0); $news = array( array('title'=>'女總理默克爾滑雪時摔倒 骨盆斷裂','date'=>'2014-1-6'), array('title'=>'駐英外交官撰文互稱對方國家為"伏地魔"','date'=>'2014-1-6'), array('title'=>'安倍:望與中國領導人會面 中方:你關閉了大門','date'=>'2014-1-6'), array('title'=>'揭秘臺灣駐港間諜網(wǎng)運作 湖北宜昌副市長被查','date'=>'2014-1-6'), array('title'=>':嫦娥三號是貨真價實的中國創(chuàng)造','date'=>'2014-1-6'), ); echo json_encode($news);
好了今天的Ajax就嘮到這,希望大家有所收獲,如果有錯誤的希望大家指正,看到好多人看頭像進來的,倫家真是不知道說什么,還是希望大家能理性多提點意見拉拉,下次會講下對于Ajax的封裝,以及一些實際應用。
以上所述是小編給大家介紹的Ajax基礎詳解教程(二)的全部敘述,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關文章
解決ajax回調(diào)函數(shù)返回的字符串亂碼問題
ajax回調(diào)函數(shù),返回的字符串亂碼問題很是讓人痛恨,下面有個不錯的解決方法,大家可以參考下2014-01-01使用jquery 的ajax調(diào)用總是錯誤親測的解決方法
使用jquery 的ajax功能調(diào)用一個頁面,卻發(fā)現(xiàn)總是出現(xiàn)錯誤,經(jīng)過這么多測試終于正常了,尤其是 dataType: 'json',看來jquery有很嚴格的驗證機制2013-07-07利用promise及參數(shù)解構封裝ajax請求的方法
這篇文章主要介紹了利用promise及參數(shù)解構封裝ajax請求的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-01-01ajax請求post和get的區(qū)別以及get post的選擇
這篇文章主要介紹了ajax請求post和get的區(qū)別以及get post的選擇,需要的朋友可以參考下2014-06-06