AJAX

一、AJAX簡介
1档痪、背景介紹:
2005年 Jesse James Garrett 發(fā)表了一篇文章,標題為:“Ajax:A new Approach to Web Applications”个唧。他在這篇文章里介紹了一種技術婉称,用 他的話說,就叫:Ajax贤牛,是 Asynchronous JavaScript AND XML 的簡寫惋鹅。 這種技術能夠向服務器請求額外的數據而無須卸載頁面(即刷新),會帶來更 好的用戶體驗殉簸。一時間闰集,席卷全球。
2般卑、什么是AJAX:
Ajax 即“Asynchronous Javascript And XML”(異步 JavaScript 和 XML)武鲁,是指一種創(chuàng)建交互式網頁應用的網頁開發(fā)技術。
Ajax = 異步 JavaScript 和 XML 或者是 HTML(標準通用標記語言的子集)椭微。
Ajax 是一種用于創(chuàng)建快速動態(tài)網頁的技術洞坑。
Ajax 是一種在無需重新加載整個網頁的情況下,能夠更新部分網頁的技術蝇率。
通過在后臺與服務器進行少量數據交換迟杂,Ajax 可以使網頁實現(xiàn)異步更新。這意味著可以在不重新加載整個網頁的情況下本慕,對網頁的某部分進行更新排拷。
傳統(tǒng)的網頁(不使用 Ajax)如果需要更新內容,必須重載整個網頁頁面锅尘。
(from:百度百科)
簡而言之:AJAX為異步無刷新技術监氢。能夠請求后臺發(fā)送和獲取數據布蔗,而無需卸載頁面(刷新頁面)。
二浪腐、XMLHttpRequest
1纵揍、XMLHttpRequest對象
* XMLHttpRequest對象是AJAX的核心對象:
XHR提供了向服務器發(fā)送請求和解析服務器響應提供了流暢的接口。 能夠以異步方式從服務器獲取更多的信息议街,這就意味著泽谨,用戶只要觸發(fā)某一事件, 在不刷新網頁的情況下特漩,更新服務器最新的數據吧雹。 雖然 Ajax 中的 x 代表的是 XML,但 Ajax 通信和數據格式無關涂身,也就是說這 種技術不一定使用 XML雄卷。
使用 XHR 對象
var xhr = new XMLHttpRequest()
在使用 XHR 對象時,先必須調用 open()方法蛤售,它接受三個參數:要發(fā)送的請求類型(get丁鹉、post)、請求的 URL 和表示是否異步悍抑。open()方法并不會真正發(fā)送請求鳄炉,而只是啟動一個請求以備發(fā)送。
通過 send()方法進行發(fā)送請求搜骡,send()方法接受一個參數,作為請求主體發(fā)送的數據佑女。如果不需要則记靡,必須填 null。執(zhí)行 send()方法之后团驱,請求就會發(fā)送到服務器上摸吠。
* 響應數據屬性和說明
當請求發(fā)送到服務器端,收到響應后嚎花,響應的數據會自動填充 XHR 對象的屬 性寸痢。那么一共有四個屬性:

屬性名                  說明 
responseText       作為響應主體被返回的文本 
responseXML       如果響應主體內容類型是"text/xml"或"application/xml", 
                             則返回包含響應數據的 XML DOM 文檔 status 響應的 HTTP 狀態(tài) 
statusText            HTTP 狀態(tài)的說明 
    *  HTTP狀態(tài)碼

接受響應之后紊选,第一步檢查 status 屬性啼止,以確定響應已經成功返回。一般 情況 HTTP 狀態(tài)代碼為 200 作為成功的標志兵罢。除了成功的狀態(tài)代碼献烦,還有一些別 的:

HTTP狀態(tài)碼  狀態(tài)字符串                說明 
200                OK                             服務器成功返回了頁面 
400                Bad Request              語法錯誤導致服務器不識別 
401                Unauthorized             請求需要用戶認證 
404                Not found                    指定的 URL 在服務器上找不到 
500                Internal Server Error   服務器遇到意外錯誤,無法完成請求 
503                ServiceUnavailable     服務器過載或維護導致無法完成請求 

注意:我們判斷 HTTP 狀態(tài)值即可卖词,不建議使用 HTTP 狀態(tài)說明巩那,因為在跨瀏覽器 的時候,可能會不太一致。
2即横、發(fā)送的請求的步驟:

1噪生、得到XMLHttpRequest對象
    new XMLHttpRequest()
2、準備請求   open(請求類型GET/POST,請求的URL,是否異步)  
    xhr.open(請求類型GET/POST,請求的URL,是否異步);
3东囚、發(fā)送請求   send([參數]) 
    xhr.send([參數])
注:如果是GET請求跺嗽,請求的參數設置在url的后面,所以send(null)
    如果是POST請求舔庶,無參數設置為null抛蚁,有參數則設置參數即可
4、判斷響應狀態(tài)惕橙,得到后臺響應
    xhr.responseText;   

三瞧甩、GET 與 POST
在提供服務器請求的過程中,有兩種方式弥鹦,分別是:GET 和 POST肚逸。在 Ajax 使用 的過程中,GET 的使用頻率要比 POST 高彬坏。
1朦促、GET請求
GET 請求是最常見的請求類型,最常用于向服務器查詢某些信息栓始。必要時务冕, 可以將查詢字符串參數追加到 URL 的末尾,以便提交給服務器幻赚。

xhr.open('get','diner/login?'+'name=Lee&age=100',true); 

通過 URL 后的問號給服務器傳遞鍵值對數據禀忆,服務器接收到返回響應數據。 特殊字符傳參產生的問題可以使用 encodeURIComponent()進行編碼處理落恼,中 文字符的返回及傳參箩退,可以將頁面保存和設置為 utf-8 格式即可,AJAX 返回的 數據為 UTF-8佳谦。
* 同步調用

/*
AJAX同步
*/
//獲取XHR對象
var xhr=new XMLHttpRequest();
//準備請求
xhr.open("GET", "js/data.json", false);
//發(fā)送請求
xhr.send(null);
//判斷狀態(tài)戴涝,并得到后臺響應responseText
if(xhr.status==200){
    console.log(xhr.responseText);
}else{
    alert("狀態(tài)碼:"+xhr.status+"錯誤信息:"+xhr.responseText);
}
    *  異步調用
同步調用固然簡單,但使用異步調用才是我們真正常用的手段钻蔑。
使用異步調的時候啥刻,檢測readyState 屬性,每當 readyState 屬性改變時,
觸發(fā)readystatechange 事件矢棚。
這個屬性有五個值:
值           狀態(tài)      說明
0           未初始化    尚未調用 open()方法
1           啟動      已經調用 open()方法郑什,但尚未調用 send()方法
2           發(fā)送      已經調用 send()方法,但尚未接受響應
3           接受      已經接受到部分響應數據
4           完成      已經接受到全部響應數據蒲肋,而且可以使用
  //獲取XMLHttpRequest對象
        var xhr =new XMLHttpRequest();
        //開啟請求:請求類型蘑拯,請求地址钝满,同步異步
        xhr.open("GET", "js/data.json", true);
        //發(fā)送參數,post有參數則設置
        xhr.send(null);
        //判斷狀態(tài)申窘,接受結果
        //需要判斷readystate 因為異步模式不能保證已經執(zhí)行完畢
        console.log(1);
         // 使用異步調用的時候弯蚜,檢測 readyState 屬性,每當 readyState 
         //屬性改變時,觸 發(fā) readystatechange事
        xhr.onreadystatechange=function(){
        if(xhr.readyState==4){          
            if(xhr.status==200){
                console.log(xhr.responseText);
            }else{
                console.log("狀態(tài)碼:"+xhr.status+"錯誤信息"+xhr.responseText+"readyState:"+xhr.readyState);
            }
        }
        console.log(2);
        }

2剃法、POST請求
POST 請求可以包含非常多的數據碎捺,我們在使用表單提交的時候,很多就是 使用的 POST 傳輸方式贷洲。

 xhr.open('post', 'diner/login', true); 

而發(fā)送 POST 請求的數據收厨,不會跟在 URL 的尾巴上,而是通過 send()方法 向服務器提交數據优构。

xhr.send('name=Lee&age=100'); 

一般來說诵叁,向服務器發(fā)送 POST 請求由于解析機制的原因,需要進行特別的 處理钦椭。因為POST請求和Web表單提交是不同的拧额,需要使用XHR來模仿表單提交。

 xhr.setRequestHeader('Content-Type','application/x-www-form-urle ncoded');

從性能上來講 POST 請求比 GET 請求消耗更多一些彪腔,用相同數據比較侥锦,GET 最多比 POST 快兩倍。
* 說明:

 post 請求德挣,需要有服務器恭垦,暫時使用 tomcat 
     將 tomcat 壓縮包在某個盤下解壓 
     將存放了 json 文件的項目放入 webapps 文件夾下 
     在 bin 目錄下,打開 startup.bat格嗅,啟動服務
    *  同步
<script type="text/javascript">
    //同步模式下 post方式
    //獲取XMLHttpRequest對象
    var request=new XMLHttpRequest();
    //開啟請求
    request.open("POST", "js/data.json", false)
    //模擬表單提交
    request.setRequestHeader('Content-Type','application/x-www-form-urle ncoded'); 
    //準備請求
    request.send(null);
    //判斷響應狀態(tài)
    if(request.status==200){
        console.log(request.responseText)
    }else{
        console.log(request.status+"--"+request.responseText);
    }   
</script>
    *  異步
<script type="text/javascript">
    //獲取對象
    var request=new XMLHttpRequest();
    //準備請求
    request.open("POST", "js/data.json", true);
    //模擬表單提交
    request.setRequestHeader('Content-Type','application/x-www-form-urle ncoded'); 
    //發(fā)送請求
    request.send(null);
    //判斷狀態(tài)和結果
    request.onreadystatechange=function(){
        if(request.readyState==4){
            if(request.status==200){
                console.log(request.responseText);
            }else{
                console.log(request.status+"--"+request.responseText);
            }
        };
    };
</script>

四署照、封裝 Ajax

因為 Ajax 使用起來比較麻煩,主要就是參數問題吗浩,比如到底使用 GET 還是 POST;我們需要封裝一個 Ajax 函數没隘,來方便我們調用懂扼。

調用者:
    請求類型    GET/POST
    請求路徑
    請求參數
    是否異步
    
封裝Ajax
    1、得到XMLHttpRequest對象
        new XMLHttpRequest()
    2右蒲、打開請求   open(請求類型GET/POST,請求的URL,是否異步)  注:三個參數都是由調用者傳遞
        注:判斷如果是POST請求阀湿,請求路徑直接設置即可;如果是GET請求瑰妄,需要拼接請求參數陷嘴;
    3、發(fā)送請求   send([參數]) 
    xhr.send([參數])
        注:如果是GET請求间坐,請求的參數設置在url的后面灾挨,所以send(null)
        如果是POST請求邑退,無參數設置為null,有參數則設置參數即可
    4劳澄、判斷響應狀態(tài)地技,得到后臺響應
        xhr.responseText;
        注:判斷是否是異步請求,如果是同步則直接獲取響應數據秒拔;
              如果是異步莫矗,則需要先判斷數據是否完全響應(readyState==4),
              再獲取響應數據
<script type="text/javascript">
/*
 * 格式化參數
 obj{
    type:
    url:
    async:
    data:{      
    }
    success:function(){     
    }
    error:function(){       
    }
}
 */
    var user={
        "type":"post",
        "url":"js/data.json",
        "async":"true",
        data:{              
        },
        success:function(result){
            console.log(result);
        },
        error:function(result){
            alert(result);
        }
    }   
    console.log(convertData(user));
    ajax(user);
    //AJAX封裝
    function ajax(obj){
        // 1砂缩、得到XMLHttpRequest對象
        var xhr = new XMLHttpRequest();     
        // 2作谚、準備請求   open(請求類型GET/POST,請求的URL,是否異步)  
        //判斷同步還是異步
        console.log(obj.type);
        if(obj.type.toUpperCase()=="GET"){
            obj.url+=obj.url.indexOf("?")>-1?"&":"?"+convertData(obj.data);     //自定義數據格式化函數    
        }
        xhr.open(obj.type,obj.url,obj.async); 
        // 3、發(fā)送請求    send(參數) 
        //xhr.send("uname=zhangsan&upwd=123456"); // Post請求有參數庵芭,則設置
        if(obj.type.toUpperCase()=="GET"){
            xhr.send(null);
        }else{
            // 模擬表單提交
            xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
            xhr.send(obj.data);         
        }
        // 4妹懒、判斷響應狀態(tài),得到后臺響應得到后臺響應  xhr.responseText;
        // 如果是異步請求喳挑,需要先知道數據是否完全響應
        // 監(jiān)聽readyState的值的變化
        if(obj.async){
            xhr.onreadystatechange = function() {
                console.log(xhr.readyState);
                // 判斷是否完全響應彬伦,即readyState的值等于4
                if (xhr.readyState == 4) {
                    getStatus();
                }
            }
        }else{
            getStatus();
        }
        //自定義返回函數
        function getStatus(){
            if (xhr.status == 200) {
                //console.log(xhr.responseText);
                obj.success(xhr.responseText);
            } else {
                obj.success("狀態(tài)碼:" + xhr.status + "-----錯誤信息:" + xhr.responseText);
                //alert("狀態(tài)碼:" + xhr.status + "-----錯誤信息:" + xhr.responseText);
            }
        }
    }
    //將json對象格式數據轉換為字符串-->"key1=value1&key2=value2&.."
    function convertData(data){
        //定義存儲數據數組
        var arr=[];
        for(var key in data){
            arr.push(key+"="+data[key]);
        }
        return arr.join("&")        
    }

</script>   

五、Jquery 的 ajax

data.json文件中內容://js/data.json路徑下
{
    "uname":"zhangsan",
    "upwd":"123456",
    "uage":18,
    "usex":true
}

1.$.ajax()

jquery 調用 ajax 方法:
            格式:$.ajax({});
            參數:
                type:請求方式 GET/POST
                url:請求地址 url
                async:是否異步伊诵,默認是 true 表示異步
                data:發(fā)送到服務器的數據
                dataType:預期服務器返回的數據類型
                contentType:設置請求頭
                success:請求成功時調用此函數
                error:請求失敗時調用此函數
$.ajax({
        type:"get",
        url:"js/data.json",
        data:{
            
        },
        dataType:"json", // 預期返回的數據的類型
        success:function(data){
            console.log(data);
        }
    });    

2.$.get()

GET請求
        1.請求 json 文件单绑,忽略返回值
            $.get('../js/cuisine_area.json');
        2.請求 json 文件,傳遞參數曹宴,忽略返回值
            $.get('../js/cuisine_area.json',{name:"tom",age:100});
        3.請求 json 文件,拿到返回值,請求成功后可拿到返回值
            $.get('../js/cuisine_area.json',function(data){
                console.log(data)
            });
        4.請求 json 文件,傳遞參數,拿到返回值
            $.get('../js/cuisine_area.json',{name:"tom",age:100},function(data){
                console.log(data)
            });
   
$.get("js/data.json",{name:"jerry",age:"25"},function(data){
        console.log(data);
    });   

3.$.post()

post請求
        1.請求 json 文件搂橙,忽略返回值
            $.post('../js/cuisine_area.json');
        2.請求 json 文件,傳遞參數笛坦,忽略返回值
            $.post('../js/cuisine_area.json',{name:"tom",age:100});
        3.請求 json 文件,拿到返回值,請求成功后可拿到返回值
            $.post('../js/cuisine_area.json',function(data){
                console.log(data)
            });
        4.請求 json 文件,傳遞參數,拿到返回值
            $.post('../js/cuisine_area.json',{name:"tom",age:100},function(data){
                console.log(data)
            });
    $.post("js/data.json",{name:"tom"},function(data){
        alert(data);
    });   

4.$.getJSON()

表示請求返回的數據類型是 JSON 格式的 ajax 請求 

$.getJSON("js/data.json",{},function(data){
        alert(data);
        console.log(data.upwd+"--"+data.uname);
    });
    
    $.getJSON("js/data.json",function(data){
        console.log(data);
    });
    $.getJSON("js/data.json");

5.jsonp

遠程跨域時区转,如果有兩個域名,從其中一個域名去訪問另一個域名時版扩,使用
        普通的 ajax 方法是獲取不到數據的废离,那么就可以使用 jsonp 方式發(fā)送請求。
        添加屬性:
        // jsonp:’callback’
        dataType:’jsonp’
        
        注:訪問的遠程路徑支持跨域
  $.ajax({
        type:"get",
        url:"http://iservice.itshsxt.com/restaurant/find",
        data:{
            cuisine:"Bar"
        },
        jsonp:"callback",
        dataType:"jsonp", // 跨域處理
        success:function(data){
            console.log(data);
        }
    });
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末礁芦,一起剝皮案震驚了整個濱河市蜻韭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌柿扣,老刑警劉巖肖方,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異未状,居然都是意外死亡俯画,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門司草,熙熙樓的掌柜王于貴愁眉苦臉地迎上來艰垂,“玉大人泡仗,你說我怎么就攤上這事〔男梗” “怎么了沮焕?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長拉宗。 經常有香客問我峦树,道長,這世上最難降的妖魔是什么旦事? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任魁巩,我火速辦了婚禮,結果婚禮上姐浮,老公的妹妹穿的比我還像新娘谷遂。我一直安慰自己,他們只是感情好卖鲤,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布肾扰。 她就那樣靜靜地躺著,像睡著了一般蛋逾。 火紅的嫁衣襯著肌膚如雪集晚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天区匣,我揣著相機與錄音偷拔,去河邊找鬼。 笑死亏钩,一個胖子當著我的面吹牛莲绰,可吹牛的內容都是我干的。 我是一名探鬼主播姑丑,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼蛤签,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了栅哀?” 一聲冷哼從身側響起顷啼,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎昌屉,沒想到半個月后,有當地人在樹林里發(fā)現(xiàn)了一具尸體茵瀑,經...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡间驮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了马昨。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片竞帽。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡扛施,死狀恐怖,靈堂內的尸體忽然破棺而出屹篓,到底是詐尸還是另有隱情疙渣,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布堆巧,位于F島的核電站妄荔,受9級特大地震影響,放射性物質發(fā)生泄漏谍肤。R本人自食惡果不足惜啦租,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望荒揣。 院中可真熱鬧篷角,春花似錦、人聲如沸系任。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽俩滥。三九已至嘉蕾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間举农,已是汗流浹背荆针。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留颁糟,地道東北人航背。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像棱貌,于是被迫代替她去往敵國和親玖媚。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內容