JavaScript—Ajax基礎知識梳理(29)

Ajax用一句話來講就是無須刷新頁面便可從服務器取得數據。注意,雖然Ajax翻譯過來叫異步JavaScript與XML,可是得到的數據不必定是XML數據,如今服務器端返回的都是JSON格式的文件。前端

完整的Ajax請求過程 完整的Ajax請求過程web

1.建立XMLHttpRequest實例 2.發出HTTP請求 3.接收服務器傳回的數據 4.更新網頁數據
下面先看一個紅寶書上給出的發起Ajax請求的例子,API的用法在後面章節給出。面試

var xhr = new XMLHttpRequest();  // 建立XMLHttpRequest實例

xhr.onreadystatechange = function(){
  if (xhr.readyState == 4){   // 判斷請求響應過程階段,4 階段表明已接收到數據
    if (xhr.status >=200 && xhr.status < 300 || xhr.status == 304) {  // 校驗HTTP狀態碼
      console.log(xhr.responseText);   // 輸出響應的文本
    } else {
      console.error(xhr.status, xhr.statusText); // 打印其餘HTTP狀態碼
    }
  }
};

xhr.open('get', 'example.txt', true); // 初始化xhr實例,或者說啓動請求
xhr.send(null);  // 設置HTTP請求攜帶參數,null爲不帶參數
複製代碼

Ajax請求過程詳解編程

  1. 建立XMLHttpRequest實例 從上面的的代碼能夠看出,建立一個XHR實例方式爲:
var xhr = new XMLHttpRequest();
複製代碼
  1. 發出HTTP請求 實例建立好後,首先須要啓動一個HTTP請求,使用XHR的open()方法,open方法接受三個參數
XMLHttpRequest.open(method, url, isAsync)
// 例如
xhr.open('get', 'http://www.baidu.com', true)
複製代碼

第一個參數爲http請求使用方法,如('get','post'等),第二是參數是請求的url, 第三個參數表明是否異步發送請求(可選)。調用open()方法後會啓動一個http請求,但它不會當即發送請求,處於待命狀態。須要注意的是:請求的url必需要跟請求源域(origin)同域,也就是說協議、域名、端口號要一致,跨域請求要使用別的方法。接着調用send()方法就會發出這個http請求。設計模式

xhr.open('get', 'http://www.baidu.com', true)
xhr.send(null)
複製代碼

send()方法接受一個參數,爲http請求發送的數據(一般用於'post'方法),若是爲null,表示不發送數據。至此,一個異步的http請求就發送到了服務器。跨域

  1. 接收服務器傳回的數據 3.1 發送同步請求 若是將open方法的第三個參數設爲false,即爲同步請求,當收到服務器的響應後,相應的數據會自動填充到XHR對象的屬性中,主要包括如下四個:
  • responseText:做爲響應主體被返回的文本。瀏覽器

  • responseXML: 響應返回的XML文檔,能接收到的前提是,響應的Content-Type字段的值爲text/xml或者application/xml。緩存

  • status: HTTP狀態碼。服務器

  • statusText: HTTP狀態碼說明。app

當客戶端收到以上信息後,首先要判斷HTTP狀態碼來確認響應是否成功,狀態碼在200-300之間表示請求成功,同時304表明請求資源未被修改,可以使用瀏覽器本地緩存。若是成功就能夠獲取響應報文主體中的數據了。

xhr.open('get', 'http://www.baidu.com', false)
xhr.send(null)

if (xhr.status >=200 && xhr.status < 300 || xhr.status == 304) {  // 校驗HTTP狀態碼
  console.log(xhr.responseText);   // 輸出響應的文本
} else {
  console.error(xhr.status, xhr.statusText); // 打印其餘HTTP狀態碼
}
複製代碼

3.2 發送異步請求 若是將open方法的第三個參數設爲true,即爲異步請求。那麼就須要一個事件來通知程序異步請求的結果是否返回。XHR對象中的readyState屬性,表示請求/響應整個過程所處的階段,它有五個值分爲對應五個階段:

0:未初始化。未調用open()方法。 1:啓動。已經調用open()方法,但未調用send()方法。 2:發送。已調用send()方法,但未收到響應。 3: 接收。已經接收到部分響應數據。 4:完成。已經接受到所有響應數據。

readyState的值每變化一次,都會觸發一次readStatechange事件,咱們定義一個事件處理函數onreadStatechange(),並監聽readyState == 4狀態,就能夠得知響應數據已所有收到,並進行下一步操做。那麼就是文章開頭給出的代碼:

var xhr = new XMLHttpRequest();  // 建立XMLHttpRequest實例

xhr.onreadystatechange = function(){
  if (xhr.readyState == 4){   // 判斷請求響應過程階段,4 階段表明已接收到數據
    if (xhr.status >=200 && xhr.status < 300 || xhr.status == 304) {  // 校驗HTTP狀態碼
      console.log(xhr.responseText);   // 輸出響應的文本
    } else {
      console.error(xhr.status, xhr.statusText); // 打印其餘HTTP狀態碼
    }
  }
};

xhr.open('get', 'example.txt', true); // 初始化xhr實例,或者說啓動請求
xhr.send(null);  // 設置HTTP請求攜帶參數,null爲不帶參數
複製代碼

補充XHR中三個有用的事件

timeout事件 當超出了設置時間還未收到響應,就會觸發timeout事件,進而調用ontimeout事件處理程序。同時timeout也是XHR的一個屬性,用於設置這個時間閾值。下面是用法:

xhr.ontimeout = function() {
  alert('timeout!')
}

xhr.open('get', 'http://www.baidu.com', true)
xhr.timeout = 1000 // 時間閾值設爲1秒
xhr.send(null)
複製代碼

load事件

load事件用於簡化對readState值的判斷,響應數據所有接收完畢後(也就是readState == 4)會觸發load事件,使用onload事件處理函數進行後續操做,onload會接收一個event對象,它的target屬性等於XHR對象,固然咱們在定義這個事件處理函數時也能夠不傳入這個參數,來看下面的用法:

var xhr = new XMLHttpRequest()
xhr.onload = function () {
  if(xhr.status >=200 && xhr.status < 300 || xhr.status == 304) {
    console.log(xhr.responseText);   // 輸出響應的文本
  } else {
    console.error(xhr.status, xhr.statusText); // 打印其餘HTTP狀態碼
  }
}
xhr.open('get', 'http://www.baidu.com', true)
xhr.send(null)
複製代碼

這樣就不用去關心readyState值的變化狀況了。固然若是想在特定readyState值上作一些邏輯處理,仍是要用以前的方法。

progress事件 這個是頗有用的一個事件,progress事件會在瀏覽器接收數據期間週期觸發,表明整個請求過程的進度,它的事件處理程序onprogress接收一個event對象,event.target是XHR對象,另外event還有三個屬性:

lengthComputable:Boolean值,進度信息是否可用。 position:已經接收到的字節數。 totalSize:總共要接收的字節數,被定義在響應報文的Content-Length字段中。

若是響應報文中有Content-Length字段,那麼咱們就能夠計算當前時刻響應數據的加載進度了,這也是以前看到的一個面試題。看下面的代碼:

xhr.onprogress = function(event) {
  if(event.lengthComputable) {
    console.log(`Received: ${(event.position/event.totalSize).toFixed(4)*100}%`);
  }
}
複製代碼

其餘還有不少有用的API,如FormData表單序列化,overrideMimeType()重寫XHR響應的MIME類型等等

這裏推薦一下個人前端學習交流羣:784783012,裏面都是學習前端的,若是你想製做酷炫的網頁,想學習編程。本身整理了一份2018最全面前端學習資料,從最基礎的HTML+CSS+JS【炫酷特效,遊戲,插件封裝,設計模式】到移動端HTML5的項目實戰的學習資料都有整理,送給每一位前端小夥伴,有想學習web前端的,或是轉行,或是大學生,還有工做中想提高本身能力的,正在學習的小夥伴歡迎加入學習。

相關文章
相關標籤/搜索