扒一扒 EventServiceProvider 原始碼

來源:互聯網
上載者:User

標籤:time   timeout   網域名稱   請求響應   更新   pos   fixed   序列化   部分   

Ajax用一句話來說就是無須重新整理頁面即可從伺服器取得資料。注意,雖然Ajax翻譯過來叫非同步JavaScriptXML,但是獲得的資料不一定是XML資料,現在伺服器端返回的都是JSON格式的檔案。

完整的 Ajax請求過程

完整的Ajax請求過程

  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();
2. 發出HTTP請求

執行個體建立好後,首先需要啟動一個HTTP請求,使用XHRopen()方法,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請求就發送到了伺服器。

3. 接收伺服器傳回的資料3.1 發送同步請求

如果將open方法的第三個參數設為false,即為同步請求,當收到伺服器的響應後,相應的資料會自動填滿到XHR對象的屬性中,主要包括以下四個:

  • responseText:作為響應主體被返回的文本。
  • responseXML: 響應返回的XML文檔,能接收到的前提是,響應的Content-Type欄位的值為
    text/xml或者application/xml
  • status: HTTP狀態代碼。
  • statusText: HTTP狀態代碼說明。

當用戶端收到以上資訊後,首先要判斷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.targetXHR對象,另外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類型等等,後面慢慢更新。

原文地址:1190000015668383

扒一扒 EventServiceProvider 原始碼

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.