AJAX及其跨域的主要解決方法

    AJAX = Asynchronous JavaScript andXML(異步的 JavaScript 和 XML)。經過在後臺與服務器進行少許數據交換,使網頁實現異步更新。要明白異步交互能夠經過同步和異步的對比很容易明白:javascript

同步交互,就是最多見的click-refresh模式,點一個鏈接或提交一個表單,而後就必須重載整個頁面java

異步交互,javascript根據返回的數據,不刷新頁面而改變當前頁面的顯示,例如:新浪微博,百度地圖。
web

   Ajax的異步交互XMLHttpRequest這個對象開始它容許經過javascript來執行HTTP請求,而且將會解析一個XML格式或者文本,json等格式的服務器響應,這個過程用戶不用等待服務器的響應,用戶能夠繼續進行其它操做。而後,服務器將數據返回,客服端對數據進行處理,能夠不刷新頁面使得用戶獲得了新數據。ajax

  下面就來看XMLHTTPRequest的五步使用法,來實現異步交互:json

  1.創建XMLHTTPRequest對象跨域

1 if(window.XMLHttpRequest){
2     var xmlhttp=new XMLHttpRequest();
3 }else if(window.ActiveXObject){//ie6
4     var xmlhttp=new ActiveXObject();
5 }

 2.註冊回調函數瀏覽器

1 xmlhttp.onreadystatechange=callback;

    給xmlhttp對象註冊onreadystatechange事件,並綁定回調函數。實際上每次readyState的值發生變化時,回調函數都會被調用,可是通常咱們只關心狀態4,表示響應已經徹底接受。服務器

  3.使用open方法設置和服務器端交互的基本信息 ,分別包含方法和交互方式,true爲異步交互。app

1 xmlhttp.open("GET","url?parmeters",true)

  4.設置發送的數據,開始和服務器端交互(因爲get方法參數附加在url中,故不須要重複發送了)異步

1 xmlhttp.send(null)

      對於post方法有些些微的不一樣:

1 //3.設置和服務器端交互的相應參數 
2  xmlhttp.open("POST","url",true); 
3 //設置post請求頭信息 
4 xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
5 //4.設置服務器端發送的數據,啓動和服務器端的交互 
6 xmlhttp.send("name=" + userName); 

  5.在回調函數中判斷交互是否結束,響應是否正確,並根據須要獲取服務器端返回的數據,更新頁面內容

1 function callback(){
2     if(xmlhttp.readyState===4){
3         if(xmlhttp.status===200){
4             var message=xmlhttp.responseXML
5         }
6     }
7 }
補充點XMLHttpRequest對象的readyState 狀態 ,總結以下:
(0)未初始化 
此階段確認XMLHttpRequest對象是否建立,併爲調用open()方法進行未初始化做好準備。值爲0表示對象已經存在,不然瀏覽器會報錯--對象不存在。
(1)載入
此階段對XMLHttpRequest對象進行初始化,即調用open()方法,根據參數(method,url,true)完成對象狀態的設置。並調用send()方法開始向服務端發送請求。值爲1表示正在向服務端發送請求。
(2)載入完成
此階段接收服務器端的響應數據。但得到的還只是服務端響應的原始數據,並不能直接在客戶端使用。值爲2表示已經接收徹底部響應數據。併爲下一階段對數據解析做好準備。
(3)交互
此階段解析接收到的服務器端響應數據。即根據服務器端響應頭部返回的MIME類型把數據轉換成能經過responseBody、responseText或responseXML屬性存取的格式,爲在客戶端調用做好準備。狀態3表示正在解析數據。
(4)完成
此階段確認所有數據都已經解析爲客戶端可用的格式,解析已經完成。值爲4表示數據解析完畢,能夠經過XMLHttpRequest對象的相應屬性取得數據。

   概而括之,整個XMLHttpRequest對象的生命週期應該包含以下階段:建立-初始化請求-發送請求-接收數據-解析數據-完成 

ajax的基本過程就是這樣了。說到AJAX就必須面臨兩個問題:

  1. AJAX以何種格式來交換數據
  2. 跨域的需求如何來解決

    這兩個問題目前有不一樣的解決方法,好比數據能夠用自定義的字符串或者XML來描述,跨域能夠用服務器端代理來解決。可是到目前爲止最優的方法仍是用JSON來傳遞數據,用JSONP來跨域

json在此再也不贅述。下文主要講跨域方法

JSONP的產生:

  1. web頁面上調用js文件則不受是否跨域的影響(不只如此,咱們還發現凡是擁有「src」這個屬性的標籤都擁有跨域的能力,標籤的src屬性並不 被同源策略所約束,因此能夠獲取任何服務器上腳本並執行。好比<script><img><iframe>)
  2. 因而能夠判斷,當前階段若是想經過純web端跨域,那就是在遠程服務器上設法把數據裝進js格式的文件裏,供客戶端調用和進一步處理;
  3. 咱們已經知道有一種叫作JSON的純字符數據格式能夠簡潔的描述複雜數據,JSON還被js原生支持,因此在客戶端幾乎能夠爲所欲爲的處理這種格式的數據;

  4. 這樣解決方案就呼之欲出了,web客戶端經過與調用腳本如出一轍的方式,來調用跨域服務器上動態生成的js格式文件(通常以JSON爲後綴),顯而易見,服務器之因此要動態生成JSON文件,目的就在於把客戶端須要的數據裝入進去。

  5.  客戶端在對JSON文件調用成功以後,也就得到了本身所需的數據,剩下的就是按照本身需求進行處理和展示了。

  6. 爲了便於客戶端使用數據,逐漸造成了一種非正式傳輸協議,人們把它稱做JSONP,該協議的一個要點就是容許用戶傳遞一個callback參數給服 務端,而後服務端返回數據時會將這個callback參數做爲函數名來包裹住JSON數據,這樣客戶端就能夠隨意定製本身的函數來自動處理返回數據了。

     jsonp的核心就是在客服端建立包含回調函數的script,將<script>中的url定向到跨域的服務器腳本上。不一樣的請求建立不一樣的回調函數,服務器端根據這個回調函數動態的生成所須要的json數據,做爲參數插入到回調函數中,客服端調用回調函數作出相應的動做。下面是一段客服端的腳本程序:

 1 <script type="text/javascript">
 2     //獲得航班信息查詢結果後的回調函數
 3     var flightHandler=function(data){
 4       alert('你要查詢的航班結果:票價'+data.price+'元,餘票'+data.tickets);
 5     }
 6     //提供jsonp服務的url地址(無論什麼地址,最後生成的都是一段javascript代碼)
 7    var url="http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
 8    //建立script標籤,並設置屬性
 9     var script = document.createElement('script');
10     script.src=url;
11     // 把script標籤加入head,此時調用開始
12     document.getElementsByTagName('head')[0].appendChild(script); 
13       </script>

     咱們看到調用的url中傳遞了一個code參數,告訴服務器我要查的是CA1998次航班的信息,而callback參數則告訴服務器,個人本地回調函 數叫作flightHandler,因此請把查詢結果傳入這個函數中。服務器端這個叫作flightResult.aspx的頁面生成了一段這樣的代碼提 供給客服端來使用:

1 flightHandler({
2     "code": "CA1998",
3     "price": 1780,
4     "tickets": 5
5 });

      咱們看到,傳遞給flightHandler函數的是一個json,它描述了航班的基本信息。一個jsonp的執行全過程順利完成!

相關文章
相關標籤/搜索