AJAX的學習筆記

AJAX的學習筆記

AJAX是異步JavaScript和XML的縮寫,它的做用是執行異步的網絡請求。由於JS是線性同步,若是須要用戶向瀏覽器發送一個請求,那麼就須要等瀏覽器接收到告終果才能繼續運行,若是發送到接受的時間太長,瀏覽器就會很長時間處於「假死」狀態,這樣的用戶體驗很很差。因而Jesse James Garrett介紹了一種新技術,即用JS執行異步網絡請求,也就是AJAX。php

XMLHttpRequest

AJAX的核心是XMLHttpRequest(簡稱XHR)對象。html

經過一個XMR對象的構造函數,咱們能夠在JS上開始寫AJAX。json

判斷瀏覽器

通常咱們用var xhr=new XMLHttpRequest()來建立新的XHR對象,可是因爲早期的IE版本並不支持原生的XHR,而是支持ActiveXObject,因此開始以前咱們須要作一個判斷:後端

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

設置onreadystatechange回調函數

設置回調函數的目的是,判斷咱們發送的請求是否成功,無論成功與否都給出一個回調響應,以讓咱們開始下一步的操做。以下:跨域

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

xhr.onreadychange=function(){   //狀態發生變化時,函數回調
  if(xhr.readyState===4){   //成功完成
    //判斷響應結果:
    if(xhr.status===200){
      //成功,經過responseText拿到響應文本:
      return success(xhr.responseText);
    }else{
      //失敗,根據響應碼判斷失敗緣由:
      return fail(xhr.status);
      }
  }else{
    //響應還在繼續。
  }
}

XHR的用法

成功建立XHR對象後,第一個要用的方法就是open(),open()方法傳遞三個參數:瀏覽器

  1. 請求的類型;
  2. 請求的地址;
  3. 是否異步發送請求,默認爲true,通常不用填。

例子:
open("get","example.php")安全

open()方法並非真正的發送請求,要發送請求還須要用到另外一個方法send()。get方式的請求不須要數據,則直接send()就行了,而post則須要把數據以字符串或者formData對象傳進去。服務器

安全限制

因爲瀏覽器的同源政策,若是你請求的地址URL的域名和你當前的頁面不一致,瀏覽器是不容許的。網絡

所謂的一致,是指徹底的一致。app

  1. www.xxx.com 和 xxx.com 是不一致的;
  2. www.xxx.com 和www.xxx.com:80 是不一致的;
  3. www.xxx.com:80 和www.xxx.com:8080是不一致的;
  4. https://www.xxx.comhttp://www.xxx.com 也是不一致的。

可是不少時候咱們須要從其餘的網站調數據,那麼怎麼來解決它呢?因此咱們須要用到跨域技術。

經常使用的技術有三種。

  1. 經過Flash插件發送HTTP請求;
  2. 經過在同源域名下架設代理服務器,JS把請求發送到代理服務器上;缺點是要在後端作多餘的開發;
  3. JSONP。

JSONP

這裏重點介紹一下JSONP(JSON with padding,參數式JSON)。因爲瀏覽器容許跨域引用JS資源,所以JSONP的原理就是經過觸發在頁面中的JS資源來引用數據。由於JSONP通常是由兩部分組成:回調函數、數據,因此咱們只要有一個JSONP格式的URL,並在頁面中準備好兩段代碼:一段是觸發JSONP中回調函數的代碼,這段代碼是用來渲染數據的;另外一段是動態生成引用JSONP的。

舉個例子:

咱們借用一個根據IP地址查詢天氣的API:http://freegeoip.net/json?cal...

這就是一個JSONP格式的URL,向這個地址請求,將獲得一個handleResponse()回調函數,執行就獲得數據。所以咱們就能夠拿出咱們準備好的兩段代碼了。

第一段:

function handleResponse(response){
  console.log("you are " + response.ip + ",which is in " + response.city + response.region_name);
}

這一段代碼是經過回調函數,把數據渲染出來。

第二段:

function getLocation(){
  var script=document.createElement("script"),
      script.src="http://freegeoip.net/json?callback=handleResponse"
  document.body.insertBefore(script,document.body.firstChild);
}

最後咱們只要執行這個getLocation的函數,就完成了跨域調取數據。

CORS

咱們在上面說到,瀏覽器的同源策略,會阻止接收跨域的請求結果,解決的方法已經在上面簡單介紹了,此外,如今大部分瀏覽器已經可以支持CORS了。

CORS(Cross-Origin Resource Sharing,跨域資源共享),這是一種規範,容許Web應用服務器進行跨域訪問控制,從而使跨域數據傳輸安全進行。

目前全部的瀏覽器都支持了這個策略,可是,咱們的IE10如下的並不在其中……

CORS的原理是使用HTTP頭部信息,讓服務器端與客戶端相溝通,以決定請求或響應是否成功。用一個簡單可是不太恰當的比喻就是,CORS就是你(客戶端)拿着一個口令(頭信息)去經過某個關卡,而這個關卡也有口令,若是你的口令和關卡的口令匹配(相同或者爲*),那麼你就能夠自由出入(跨域請求經過),若是不匹配,你就會被扣留(跨域請求失敗)。

所以,在CORS中,關鍵的是服務端的口令(頭信息)。只要服務端實現了CORS接口,就能夠跨域通訊。而在客戶端中,只要在open()方法的URL中使用絕對定位便可實現CORS,而CORS通訊過程,都是由瀏覽器完成,不須要用戶處理,那麼,瀏覽器是怎麼處理的呢?

兩種請求

瀏覽器把跨域請求分爲兩類:簡單請求和預先請求。

簡單請求須要知足下列兩個條件:

  • 請求方法是下列之一:

    1. GET
    2. HEAD
    3. POST
  • 請求頭中的Content—Type請求頭的值是下列之一:

    1. application/x-www-form-urlencoded
    2. multipart/form-data
    3. text/plain

反之,不知足其中之一則是預先請求。瀏覽器會先發送一個OPTION請求,用來與域名服務器協商是否能夠發送實際的跨域請求。

兩種請求的具體流程過多,這裏我就不細說了,有興趣的小夥伴能夠從下面幾篇文章中更詳細地瞭解CORS:

  1. 廖雪峯的AJAX教程
  2. 阿里雲:CORS——跨域請求那些事兒
  3. 跨域資源共享 CORS 詳解 - 阮一峯的網絡日誌
  4. HTTP訪問控制(CORS) - HTTP | MDN
總之咱們只要明白,CORS是一種跨域策略。瀏覽器會在咱們須要跨域操做時自定義頭部信息,與服務端進行匹配,以肯定是否贊成跨域。而頭信息的處理,通常狀況下,是由瀏覽器自動完成,不須要開發者處理。
相關文章
相關標籤/搜索