在上篇文章給大家介紹了Ajax基礎詳解教程(一),講到Ajax中open方法的第三個參數非同步和同步的問題,今天呢,就來繼續往下嘮,先接著上回的代碼
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();//提交請求//等待伺服器返回內容 xhr.onreadystatechange = function() { if ( xhr.readyState == 4 ) { //如果內容響應成功,並解析完成alert( xhr.responseText ); //彈出內容 } }}
下面我們就講到 ,xhr.send();這一句呢才是真正請求資料的,open方法只是設定了一些請求參數。
現在呢請求遞交了,就等伺服器回應了,這個時候Ajax的一個屬性就要登場了,那就是 responseText ,ajax請求返回的內容都放在了這裡面,而且不管你請求的內容是什麼,這裡存放的都是是字串類型。
當然我們上文也提到了,要想用非同步請求呢,這裡需要條件判斷才知道服務端對請求的內容是否響應完畢,這個時候另一個屬性就要登場了,readyState,他代表著Ajax請求過程的不同的狀態,參數如下:
0 (初始化)還沒有調用open()方法
1 (載入)已調用send()方法,正在發送請求
2 (載入完成)send()方法完成,已收到全部響應內容
3 (解析)正在解析響應內容(因為收到的內容 並不是人能看懂的內容,所以需要解析)
4 (完成)響應內容解析完成,可以在用戶端調用了
由上我們可以得到,在狀態2的時候已經回應了請求的內容了,但是這個內容我們人看不懂撒,機器才懂,所以就有3,幫我們解析這個內容,然後解析完成就變成4了,這個時候的內容,咱們前端就可以用了。
狀態是有了,可咱們怎麼能知道啥時候是啥狀態呢,這個時候我們就要用到一個監控狀態的事件了onreadystatechange事件,當狀態值改變的時候觸發會觸發這個事件,所以當狀態為4的時候我們再彈出內容。
上面的代碼基本已經瞭解了原理,不過當然不是最完善的,這個時候,我們雖然監控到了狀態,響應了內容,但是內容不一定就是對的呀,比如可能內容出錯了,可能我們請求了一個不存在的頁面,這個時候readyState是無法判斷錯誤的,我們需要知道內容是否正常,這個時候另一個屬性 status屬性就登場了,它代表的不是Ajax狀態,而是伺服器(請求資源)的狀態, http狀態代碼。狀態代碼有很多,其中比較出名的就是200,成功狀態代碼,和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();//提交請求//等待伺服器返回內容 xhr.onreadystatechange = function() { if ( xhr.readyState == 4 ) { if(xhr.status == 200) {//如果響應成功,並且伺服器相應內容正確alert( xhr.responseText );//彈出內容 }else{alert('出錯了' + xhr.status); //否則告知出錯並彈出錯誤原因} }}
Ajax的大概流程就是這樣的。當然還存在一些細節方面的問題需要注意的,繼續往下看把。
工作當中 向後端傳遞資料存在的問題:
GET請求:
1 緩衝問題:後台更改了 因網址未變 所以會去緩衝提取內容 而不是後台
來看個栗子:假如我們要點擊按鈕彈出名字和年齡,因為GET請求是通過數值串聯然後在網址傳遞資料的,所以我們的open方法可以直接這樣寫:
xhr.open('get','1.get.php?username=沐晴&age=21',true);
後台代碼不變
<?phpheader('content-type:text/html;charset="utf-8"'); //設定編碼格式,以及文件類型error_reporting(0);$username = $_GET['username'];//擷取get請求方式的資料$age = $_GET['age'];echo "你的名字:{$username},年齡:{$age}"; //輸出內容
現在點擊肯定會彈出你的名字沐晴,年齡21 了。
這個時候呢,瀏覽器會有一個緩衝,如果下次訪問相同的網址,就會從緩衝裡取。
比如我現在想彈出,歡迎你,你的名字沐晴,年齡21,
echo "歡迎,你的名字:{$username},年齡:{$age}"; //輸出內容
雖然後台代碼變了,但是GET請求訪問網址依然是 1.get.php?username=沐晴&age=21,所以後台會去瀏覽器緩衝找,結果彈出的還是原來的。大家可以自行測試。
所以,這個時候我們需要解決緩衝問題。既然訪問網址不變的話會去找緩衝,那麼我們讓網址一直變不就好了。所以我們可以在後面加個一直變化的變數,比如系統事件,或者加一個隨機數都行,像下面這樣:
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 上節課我們知道,在表單裡面傳統方式POST請求的內容是放在要求標頭裡的,那麼Ajax是放在哪裡的呢?
post 資料放在send裡面作為參數傳遞。
2 還有一點是,我們上次我們知道表單裡面的第三個參數:enctype: 提交的資料格式,預設是application/x-www-form-urlencoded,但是在Ajax中,你不寫就沒有,沒有預設值,所以我們需要在要求標頭裡面指定提交的資料格式,不然瀏覽器不知道用哪種格式解析。
所以post請求需要設定下面這兩句
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');xhr.send('username=沐晴&age=21&');
無緩衝問題,因為單單是往伺服器提交資料,提交資料是不會被緩衝的,擷取資料才會被緩衝。這就是web的機制。
前面講的都是請求資料,現在來看一下後端接收請求,然後響應給我們的內容。
先看看後端對資料的處理:後端的資料類型也是很多的,我們不能直接把這樣的資料給前端吧,所以後端也需要做一定的處理,它有個方法 json_encode 可以根據資料類型不同,然後輸出不同格式。看下面的栗子
<?phpheader('content-type:text/html;charset="utf-8"');error_reporting(0);$arr1 = array('le','mo'); // 索引類型的資料$arr2 = array('username'=>'le','age'=>32); // 2 對應關係的資料echo json_encode($arr1); // ["le","mo"] 索引類型 輸出為數組格式echo json_encode($arr2); // {"username":"le","age":32} 對應關係的資料 輸出為json格式
雖然後端輸出的內容格式上是數組和json但是我之前提到過 alert( xhr.responseText );//這裡彈出的可都是字串類型,所以儘管格式上看著是json和數組,但實際的資料類型還是字串。
所以我們前端要對這些字串進行轉換。這個時候就用到了兩個方法
1 stringify() : 把json對象轉化成字串 轉換後的字串是嚴格的json格式
2 parse() : 把字串轉成對象,可以把後端返回的字串 轉成JSON格式,對於json,只能轉換嚴格json格式的字串,字串的鍵 比較用雙引號括起來 像這樣 {"username":"le","age":32}
下面來看個實際的案例:
需求:點擊頁面按鈕,實現頁面不重新整理,在下面顯示新聞列表 看注釋應該能看懂
<!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 ); 後端傳來的格式是一個數組裡面很多條json 自己可以測試下var data = JSON.parse( xhr.responseText ); // 將後台擷取的內容轉為json類型 每一個json裡面有兩個鍵:title和datevar oUl = document.getElementById('ul1'); //擷取顯示新聞列表的節點var html = '';for (var i=0; i<data.length; i++) { // 迴圈所有的json資料,並把每一條添加到列表中html += '<li><a href="">'+data[i].title+'</a> [<span>'+data[i].date+'</span>]</li>';}oUl.innerHTML = html; //把內容放在頁面裡} else {alert('出錯了,Err:' + xhr.status);}}}}}</script></head><body><input type="button" value="按鈕" id="btn" /><ul id="ul1"></ul></body></html> <?phpheader('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'=>'揭秘台灣駐港間諜網運作 湖北宜昌副市長被查','date'=>'2014-1-6'),array('title'=>':ECS Operations and Maintenance System三號是貨真價實的中國創造','date'=>'2014-1-6'),);echo json_encode($news);
好了今天的Ajax就嘮到這,希望大家有所收穫,如果有錯誤的希望大家指正,看到好多人看頭像進來的,倫家真是不知道說什麼,還是希望大家能理性多提點意見拉拉,下次會講下對於Ajax的封裝,以及一些實際應用。
以上所述是小編給大家介紹的Ajax基礎詳解教程(二)的全部敘述,希望對大家有所協助,如果大家有任何疑問請給我留言,小編會及時回複大家的。在此也非常感謝大家對雲棲社區網站的支援!