一,js中的ajax
ajax(Asynchronous Javascript And XML)即為異步的JavaScript和XML,顧名思義,這個技術是和我們當前頁面刷新無關的,因為它是異步的,在沒有ajax的時候,我們如果去請求數據庫中的數據就要將當前頁面進行刷新,最常用的你可以想到我們的表單驗證部分,以前都是填完了所有的表單去一次性驗證,像這樣的注冊界面,你填錯了就要刷新頁面從頭再來,所以,現在有了ajax你可以填一個表格就進行一次驗證,而且頁面並不會刷新.
對於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的區別:
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的用法:
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的狀態:
0:請求沒有發出(在調用open之前)
1:請求已經建立但還沒有發出
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使用的多一點,其他中方法就不提啦,文章中可能會有一些知識點被漏掉,畢竟是自己的一個小總結,希望能對大家有點小幫助.