ajax詳解

 一,js中的ajaxphp

 ajax(Asynchronous Javascript And XML)即爲異步的JavaScript和XML,顧名思義,這個技術是和咱們當前頁面刷新無關的,由於它是異步的,在沒有ajax的時候,咱們若是去請求數據庫中的數據就要將當前頁面進行刷新,最經常使用的你能夠想到咱們的表單驗證部分,之前都是填完了全部的表單去一次性驗證,像這樣的註冊界面,你填錯了就要刷新頁面從頭再來,因此,如今有了ajax你能夠填一個表格就進行一次驗證,並且頁面並不會刷新.html

  對於ajax,他的核心技術是對象,它的整個做用過程實際上是當前頁面繼續工做,它會本身開一個時空隧道和當前界面一塊兒工做,就行兩個平行空間同樣,它的整個過程能夠總結爲先建立XMLHttpRequest對象,而後鏈接服務器,發送請求,最後接受服務器發送過來的數據,好了,XMLHttpRequest是一個可讓咱們前端和後端鏈接起來的十分神奇的對象,咱們首先來建立一個XMLHttpRequest對象前端

  

 var xhr =null;
        if(window.XMLHttpRequest){
            xhr = new XMLHttpRequest();
        }else{
            xhr = new ActiveXObject('Microsoft.XMLHTTP');

        }
//這裏進行的是針對IE瀏覽器的兼容性處理,在IE中,咱們的xmlhttprequest對象就變成了activeobject,並且裏邊的參數是不能少的,IE就是這樣倔強

  當咱們擁有了一個xhr實例後,咱們就能夠進行向數據庫中發送請求,這裏咱們先來看一下咱們須要用的方法,open()方法是創建前端到服務器的請求,而send方法是向服務器發送請求,也就是說,當咱們在叫外賣的時候,咱們用的美團就像是open()方法,創建咱們和店家的聯繫,而快遞小哥就是咱們的send()方法,他將咱們的美味給咱們送過來,這裏咱們先用get方法作一個示例,在下一塊咱們再區看一下咱們的兩種請求方法get和se的區別:ajax

var url ="index.php?id=1";
xhr.open('get',url,'true');//open中有三個參數,第一個參數用來指定使用get仍是post方式提交,第二參數是指定要發送的url地址,第三個參數指定是否使用異步,第三個參數默認是true;
xhr.send();

  這是咱們已經使用get方式向index.php發送了一個請求,咱們穿過去的參數爲"id=1";那麼咱們先來看一下和get和post區別,get和post都是用來進行發送數據的方式,從字面意思來看,get(獲得)是從數據庫獲得東西的請求方式,而post(發送)是要給服務器傳送數據的,並且post方式傳送數據是通過加密的,post傳送的數據放在請求體裏邊,而get方式只有請求頭,沒有請求體,因此get也能夠傳給數據庫少許數據,發送的方式是在url地址後邊用?作表示,若是有多個參數用&隔開,咱們先來看一下post的用法:chrome

var url = "index.php";
var data = "id=1";
xhr.open('post',url,true);
xhr.setRequestHeader('Contenttype','application/x-www-form-urlencoded')//post請求須要設置請求頭信息 xhr.send(data);
//在這裏將數據發送過去,

  那麼如今咱們已經簡單的向服務器端發送了請求,咱們正常的一個流程是,服務器會根據咱們的參數或者是它自身運算的結果來給咱們返回數據,這裏咱們並非必定要發送給數據庫參數的,舉個例子,服務器裏有一個數組["0":"蘋果","1":"橘子","2":"香蕉"],如今若是咱們不傳參,服務器會將這一個數組都return給咱們,若是咱們穿一個id=1,這時返回的數據就是橘子,咱們要理解的就是,咱們傳的參數和數據對於咱們得到數據只是一個輔助做用,真正起做用的仍是服務器內部的結構,那麼咱們如今發送了請求後,咱們面臨一個問題,咱們怎麼判斷請求是否發送成功以及服務器時候處理了咱們的請求,還有若是服務器響應了,它返給咱們的數據咱們該怎麼去獲取呢?數據庫

  好的,讓咱們來看一下,xhr實例上有一個readystate屬性,這個屬性的表明着當前xmlHttpRequest的狀態:json

    0:請求沒有發出(在調用open以前)後端

    1:請求已經創建但尚未發出api

    2:請求已經發出跨域

    3:請求正在處理當中

    4:請求已經被服務器處理完畢,相應準備就緒

  每當readystate狀態改變的時候,就會調用onreadystatechange()這個函數,因此咱們能夠在onreadystatechange進行相應狀態的判斷以及相應返回數據的獲取,當readystate爲4時,表明着咱們的請求被服務器成功的執行,但咱們還須要判斷,咱們的須要的數據是否成功被返回了呢?咱們還有一個status屬性,而這個status也有不少的狀態碼錶明着不一樣的響應狀態,其中200表明着響應成功,而且將響應的數據返回到了前端中:

  

xhr.onreadystatechange = function(){
     if(xhr.readystate == 4){//請求已經成功被處理
         if(xhr.status == 200){//成功的從服務器獲得了響應
             //這裏進行處理返回的數據
        }
    }
}

  獲得了響應以後,responseText表示字符串形式的相應數據,responseXML表示獲取XML形式的響應數據,getAllResponseHeader():獲取全部的響應報頭,這裏咱們來完整的寫一個ajax請求:

 var xhr =null;
    if(window.XMLHttpRequest){
        xhr = new XMLHttpRequest();
    }else{
        xhr = new ActiveXObject('Microsoft.XMLHTTP');

    }
    var url ="index.php?id=1";
    xhr.open('get',url,'true');//open中有三個參數,第一個參數用來指定使用get仍是post方式提交,第二參數是指定要發送的url地址,第三個參數指定是否使用異步,第三個參數默認是true;
    xhr.send();

    xhr.onreadystatechange = function(){
        if(xhr.readystate == 4){//請求已經成功被處理
            if(xhr.status == 200){//成功的從服務器獲得了響應
                   alert(responseText);
                }
        }
    }相應的後端會在後邊用php實現一個小的demo

二,XML和json

  當咱們完成了發送請求而且從後端獲取了數據後,咱們應該再進一步的去思考,那麼我能夠指定從後端傳過來的數據嗎?那麼接下來就出現了咱們的json和XML數據格式,這兩種都是咱們進行前端和後端進行傳送數據的格式,那麼咱們先來看一下XML,XML數據其實你也能夠看作咱們的html標籤,只不過它是咱們能夠自定義的標籤,你能夠給它的標籤名取的頗有意義,那樣就會很方便你去使用:

  

<china>
    <province name='河南'>
     <city>鄭州</city>
    </province>
    
</china>
//這就是一個簡單的XML格式的數據,咱們對於這樣的數據進行操做的時候可使用js操做DOM對象的方法,
//xml數據必須有一個根節點

  另一種常用的數據格式就是json了,json是一種獨立於語言的數據格式,就是說它是能夠在不少種語言中使用的,不限定於某一個特定的語言,並且它相較於xml來講代碼量較小,並且易於解析,xml就有些數據量龐大解析不便了,可是礙於json出現的較晚,因此如今大部分人仍是使用的xml,無奈與不少後端數據都是用xml存儲,json的格式有些相似於咱們的JavaScript中的對象字面量:

  

{"name":"james",
  "hobby":"basketball",
    "son" : {"littleson":"er","bigson":"san"}
}//這種就是一個簡單的json格式數據,json數據代碼量較小,可是可讀性來講
仍是xml看着比較順眼,可是人看着不順眼的代碼塊偏偏是機器最喜歡的

  獲得了數據,咱們還須要去解析一下才可以使用,相較於xml有些dom同樣的解析方法,xml的解析在js中最長用的解析方法就是json.parse()了,而將js對象轉化爲json對象咱們使用json.stringify(),固然了,json和xml的區別還有不少,這裏我獻上一個前輩的總結,很詳細的一個總結: http://www.cnblogs.com/SanMaoSpace/p/3139186.htm

三,ajax在jQuery中

  那麼咱們以前已經看了ajax在js中的應用,jQuery號稱是js的最強悍的一個封裝庫,怎能沒有ajax的封裝呢?咱們先來簡略的看一下jQuery源碼中對於ajax的封裝:

//它的大概位置在七千行左右
jQuery.extend({

    ajax: function( url, options ){}
});
//從這個大概形式中,咱們能夠看得出來,ajax時封裝在jQuery的工具方法中,是在jQuery上直接封裝的,因此調用的時候直接使用jQuery這個函數就行,因此咱們對於它的調用就是$.ajax();

  那麼咱們仍是寫一個簡單的post請求方式在jQuery中的應用:

 $.ajax({
                    type:"post",  //請求方式
                    url:"a.php", //服務器的連接地址
                    dataType:"json", //傳送和接受數據的格式
                    data:{
                        username:"james",
                        password:"123456"
                    },
                    success:function(data){//接受數據成功時調用的函數
                       console.log(data);//data爲服務器返回的數據
                    },
                    error:function(request){//請求數據失敗時調用的函數
                        alert("發生錯誤:"+request.status);
                    }
});

有了post請求方式的例子,想必get方式的寫法你們也不在話下,看着jQuery的例子,是否是感受很簡單呢,不少兼容性的處理jQuery都已經幫咱們作好了,就是這個feel.

四,跨域請求

  在上邊的例子中,咱們使用ajax請求的都是在本地和咱們同源的文件,由於JavaScript在設計時出於安全方面的考慮,不容許跨域請求,那麼什麼狀況纔算是跨域呢?

  上邊的就是咱們的不一樣源的狀況,遇到這種狀況,再去使用上邊所講的方式就不行了,那麼咱們該怎樣去解決跨域請求的問題呢?JSONP(JSON with Padding)是 JSON 的一種「使用模式」,可用於解決主流瀏覽器的數據訪問問題,由於html的<script>元素標籤能夠從其餘來源動態的加載數據,因此咱們能夠利用<script>標籤來實現跨域請求,這種方式就成爲jsonp,固然了,jsonp和json可不是一回事,json是數據的一種傳輸格式,而jsonp是一種跨域請求方式,簡單的理解就是:

<html>
<body>
    <script src='test.js'></script>
</body>
</html>
//script中的src沒有同源限制,它能夠加載其餘任意文件.而jsonp利用的就是這一個功能展開的

 對於jsonp這種跨域請求方式,咱們首先先來寫一個例子,而後再根據這個例子去慢慢的介紹:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jsonp</title>
</head>
<body>
<script src="http://cdn.weather.hao.360.cn/api_weather_info.php?app=hao360&_jsonp=weather&code=131111"></script>
//這是360天氣的一個天氣預報的一個api接口,

</body>
</html>

  當咱們運行上邊例子後,在chrome瀏覽器中打開開發者模式->點擊network->查看請求包->點擊response,這時咱們能夠查看到:

 

  是的這時候遠方的數據庫中向咱們返回了一大串數據,仔細觀察的話,不難發現,這一串數據的格式就是weather( 數據  );咦,這不是一個weather函數調用嗎?是的,沒錯,咱們的數據庫向咱們返回的就是一個函數調用,在看一下,咱們script中的url地址後邊的參數_jsonp=weather,咱們將它改成tianqi發現返回的是一個tianqi().哦,原來_jsonp參數是指定服務器返還給咱們的函數名,那麼函數中的參數就是服務器返還給咱們的數據,那麼咱們也發現此時瀏覽器已經報錯了:

  那麼也就是說咱們的代碼中沒有weather這個函數,加上上邊的講解,咱們這時應該去直接的說一下它的運行機制了,執行完script中的跨域調用後,會直接調用weather函數,因此這時候咱們要再代碼中寫一個爲weather函數讓script來執行,那麼weather函數中的參數就是咱們要的數據,咱們這時就能夠在weather函數中直接使用咱們的數據了,這裏還要說明一點,jsonp只有get請求方式,也就是傳參都要再url後邊,並且其中的數據傳輸格式都爲json,

  

<script>
    function weather(data){//回調函數
        console.log(data);
    }
</script>
<script src="http://cdn.weather.hao.360.cn/api_weather_info.php?app=hao360&_jsonp=weather&code=111111"></script>

這時咱們就能夠看到結果:

  在這裏咱們使用jsonp調用數據時,咱們須要先去了解一下後臺數據的格式,由於咱們要去傳一些參數進行獲取數據,因此前端後端是不分家的,那麼咱們當天也可使用動態加載script標籤的方法來進行點擊按鈕獲取數據

 function createScript(){
        var script = document.createElement('script');
        var url    = "http://cdn.weather.hao.360.cn/api_weather_info.php?app=hao360&_jsonp=weather&code=";
        script.src = url+params;
        document.body.appendChild(script);
    }//使用這個函數就能夠動態的加載數據了

  那麼下邊咱們來看一下jQuery中jsonp的使用:

   $.ajax({
                type:'get',
                url:天氣預報接口,
                async:'true', // 是否爲異步調用
                dataType:'jsonp', 指定數據傳輸方式
                jsonp:'jsoncallback',     //回調函數名的key值 可省略
                jsonpCallback:'XBox',       //回調函數的函數名 可省略
                success:function(data){
                   //成功後執行的函數,data就是咱們要獲取的函數值
                },
                error  :function(){
                     //失敗時執行的函數
               }

   得到數據咱們能夠顯示在HTML標籤中,有了這種異步調用方式,咱們就能夠去作一些很好玩的東西了,什麼天氣預報,快遞查詢,音樂播放器了,都不在話下,固然,跨域調用還有不少種,但我就對jsonp使用的多一點,其餘中方法就不提啦,文章中可能會有一些知識點被漏掉,畢竟是本身的一個小總結,但願能對你們有點小幫助.

相關文章
相關標籤/搜索