Ajax相信大家都聽說過,接下來這幾篇文章就來說說關于Ajax的一些知識,從而也順道引出來在實際工作過程中經常使用的一下技術:跨域。
首先我們先來看Ajax,Ajax簡單的來說,就是一個異步的javascript請求,用來獲取后臺服務端的數據,為什么要異步的呢?很簡單,因為獲取后臺網絡數據是需要時間的,如果同步的話,將會講當前界面卡住,造成非常不友好的用戶體驗。
在元素JS中來實現Ajax主要的類就是XMLHttpRequest,它的使用一般有四個步驟:
1、創(chuàng)建XMLHttpRequest對象
2、準備發(fā)送網絡請求
3、開始發(fā)送網絡請求
4、指定回調函數
沒錯,就是這么簡單的四個步驟,下面我們就通過代碼來將這四個步驟實現出來。
第一步,創(chuàng)建XMLHttpRequest對象
varxhr=newXMLHttpRequest();
第二步:準備發(fā)送網絡請求
xhr.open('get','./01check.php?username='+uname+'&password='+pw,true)
調用open方法,這里面有三個參數,第一個參數代表的這個Http請求是以get方式還是post方式,如果是get請求,則如果有參數的話,則需要將參數跟在url的后面,而如果是post請求,參數應該跟在請求體中。
第二個參數就是這個Http請求的url地址。這個url地址后面是否有?加參數,得取決于第一個參數是get還是post
第三個參數代表這個Http請求是同步的還是異步的。false代表同步,true代表異步。這個參數一般都是寫true,因為誰都不想在網絡請求的時候,將這個網頁卡住吧?不過對于學習來說的話,我們等等可以測試一下false的效果。
第三步:開始發(fā)送網絡請求
xhr.send(null);
調用send方法,傳遞一個null。需要注意的是,如果你在第二步的請求方式為get的話,那么這里傳null,如果在第二步的請求方式為post的話,這里就需要傳入你所需要傳遞給服務器的參數了。因為之前我們說過,post請求的參數并不是跟在url后面的,而是跟在請求體中,而send方法中的參數就是會被設置到請求體中。因此,對于post請求,需要在這里傳遞參數。如:
varparam='username='+uname+'&password='+pw;
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send(param);
需要注意的是,如果使用post請求,并且又有參數的話,那么對于xhr就必須設置請求頭信息,否則服務端接受不到參數。這個寫法都是固定的,如有需要直接復制即可,不需要背。
第四步,指定回調函數,xhr.send方法調用完之后,http請求就發(fā)送出去了。由于在第二步中,我們設置了請求為異步請求,異步請求不能直接獲得結果,只能通過監(jiān)聽回調的方式來得到響應數據。
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if(xhr.status==200){
alert(xhr.responseText);
}
}
}
上訴代碼的4和200代表的正常得到數據,服務器響應正常,那么這時候我們就可以通過xhr.responseText來獲取到服務器給我們返回的數據了。
這里給出readyState和status的常用值代表含義的對應關系
好,通過上訴步驟,我們就能實現Ajax來完成異步請求了。完整的代碼如下:
get請求:
<scripttype="text/javascript">
window.onload=function(){
varbtn=document.getElementById('btn');
btn.onclick =function(){
varuname=document.getElementById('username').value;
varpw=document.getElementById('password').value;varxhr=newXMLHttpRequest();
xhr.open('get','./01check.php?username='+uname+'&password='+pw,true);xhr.send(null);xhr.onreadystatechange =function(){
if(xhr.readyState ==4){
if(xhr.status ==200){
vardata=xhr.responseText;
}
}
}
}
}
script>
post請求:
<scripttype="text/javascript">
window.onload=function(){
varbtn=document.getElementById('btn');
btn.onclick =function(){
varuname=document.getElementById('username').value;
varpw=document.getElementById('password').value;varxhr=newXMLHttpRequest();
xhr.open('post','./01check.php',true);
varparam='username='+uname+'&password='+pw;
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send(param)xhr.onreadystatechange =function(){
if(xhr.readyState ==4){
if(xhr.status ==200){
vardata=xhr.responseText;
}
}
}
}
}
script>
關于原生的Ajax請求,還有一點需要說明的就是在第二個步驟設置的同步還是異步的標識位。也就是xhr.open方法的最后一個參數,這個值一般都是true,但是總有人愛裝牛角尖,就會問如果是false會怎樣?
前面已經說過了,這個值true代表是異步請求服務器的數據,false代表同步請求服務器的數據。如果是同步請求,那么在xhr獲取到數據之前,整個瀏覽器都是卡在send方法等待數據返回,所以此時用戶操作界面是沒有任何效果的,按鈕點擊不了,頁面也滾動不了,體驗非常的差。這里需要說明的是,如果真有人把這個參數寫成false的話,那么在第四步中獲取數據的方式將會有所改變。如下:
<scripttype="text/javascript">
window.onload=function(){
varbtn=document.getElementById('btn');
btn.onclick =function(){
varuname=document.getElementById('username').value;
varpw=document.getElementById('password').value;varxhr=newXMLHttpRequest();
xhr.open('get','./01check.php?username='+uname+'&password='+pw,false);xhr.send(null);if(xhr.readyState ==4){
if(xhr.status ==200){
vardata=xhr.responseText;
}
}
}
}
script>
注意到沒有,如果是同步請求的話,那么我們就不需要監(jiān)聽onreadystatechange方法。因為xhr在send方法調用的時候,是一直卡在這個方法中的。一旦這個方法結束,那么xhr就已經成功的訪問到服務器的數據了,不需要做readystatechange的監(jiān)聽。換句話說,這時候readystatechange也監(jiān)聽不到了。因為xhr.onreadystatechange = function(){}這行代碼是在xhr.send之后調用的,對于同步方法來說,send方法中xhr.readystate已經發(fā)生了變化,最后變?yōu)?之后才跳出send方法繼續(xù)向下執(zhí)行。
最后,還需要講一個稍微不太重要的東西,就是XMLHttpRequest的創(chuàng)建對于低版本的IE需要做兼容。因為低版本的IE可能沒有XMLHttpRequest這個對象。做法如下:
varxhr=null;
if(window.XMLHttpRequest){//能力測試
xhr=newXMLHttpRequest();//標準}else{
xhr=newActiveXObject("Microsoft.XMLHTTP");
}
好,到目前為止呢,我們就講了關于Ajax在原生js下的使用方式和注意事項,總結來說有以下幾點:
1、XMLHttpRequest對象創(chuàng)建的兼容處理
2、get請求post請求在代碼上有什么差異
3、同步和異步的影響,以及同步和異步獲取數據的差異。
其實在實際開發(fā)中,我們比較少自己使用原生的js代碼來實現Ajax,而是使用第三方庫,比如jQuery,那么jQuery如何來使用Ajax,我們自己能不能封裝一個類似jQuery一樣的Ajax調用方式呢?我們下一篇文章再來說明一下。