原生實現ajax解析--XMLHttpRequest

ajax基礎:javascript

Asynchronous JavaScript and XML,意思就是用JavaScript執行異步網絡請求。
若是仔細觀察一個Form的提交,你就會發現,一旦用戶點擊「Submit」按鈕,表單開始提交,瀏覽器就會刷新頁面,而後在新頁面裏告訴你操做是成功了仍是失敗了。若是不幸因爲網絡太慢或者其餘緣由,就會獲得一個404頁面。一次HTTP請求對應一個頁面。

若是要讓用戶留在當前頁面中,同時發出新的HTTP請求,就必須用JavaScript發送這個新請求,接收到數據後,再用JavaScript更新頁面,這樣一來,用戶就感受本身仍然停留在當前頁面,可是數據卻能夠不斷地更新。

AJAX請求是異步執行的,也就是說,要經過回調函數得到響應。
下面是基於原生js的ajax運用
ex:
 function success(text) {
    var textarea = document.getElementById('test-response-text');
    textarea.value = text;
  }
  
  function fail(code) {
    var textarea = document.getElementById('test-response-text');
    textarea.value = 'Error code: ' + code;
  }
 
  var request;
  if (window.XMLHttpRequest) {
    request = new XMLHttpRequest(); // 新建XMLHttpRequest對象
  } else {    // 對於低版本的IE,須要換一個ActiveXObject對象:
    request = new ActiveXObject('Microsoft.XMLHTTP');//新建Microsoft.XMLHTTP對象
  } //低版本兼容寫法
 
  request.onreadystatechange = function () { // 狀態發生變化時,函數被回調
    if (request.readyState === 4) { // 成功完成
      // 判斷響應結果:
      if (request.status === 200) {
        // 成功,經過responseText拿到響應的文本:
        return success(request.responseText);
      } else {
        // 失敗,根據響應碼判斷失敗緣由:
        return fail(request.status);
      }
    } else {
      // HTTP請求還在繼續...
    }
  }
 
  // 發送請求:
  request.open('GET', '/api/categories');
  request.send();
 
  alert('請求已發送,請等待響應...');

 

現代瀏覽器上的AJAX主要功能實現基於XMLHttpRequest對象

  XMLHttpRequest對象:
    
    可參考資料:XMLHttpRequest 對象(未收錄)   http://www.w3school.com.cn/xmldom/dom_httprequest.asp
              XML DOM - XMLHttpRequest 對象(已收錄)  http://www.w3school.com.cn/xmldom/dom_http.asp
              AJAX(收錄部分)  https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/001434499861493e7c35be5e0864769a2c06afb4754acc6000

    屬性:

      readyState:
      HTTP 請求的狀態.當一個 XMLHttpRequest 初次建立時,這個屬性的值從 0 開始,直到接收到完整的 HTTP 響應,這個值增長到 4。
      5 個狀態中每個都有一個相關聯的非正式的名稱,下表列出了狀態、名稱和含義:
      
readyState 的值不會遞減,除非當一個請求在處理過程當中的時候調用了 abort() 或 open() 方法。每次這個屬性的值增長的時候,都會觸發 onreadystatechange 事件句柄。

      responseText:
      目前爲止爲服務器接收到的響應體(不包括頭部),或者若是尚未接收到數據的話,就是空字符串。
      若是 readyState 小於 3,這個屬性就是一個空字符串。當 readyState 爲 3,這個屬性返回目前已經接收的響應部分。若是 readyState 爲 4,這個屬性保存了完整的響應體。

      responseXML:
      對請求的響應,解析爲 XML 並做爲 Document 對象返回。

      status:
      由服務器返回的 HTTP 狀態代碼,如 200 表示成功,而 404 表示 "Not Found" 錯誤。當 readyState 小於 3 的時候讀取這一屬性會致使一個異常。

      statusText:
      這個屬性用名稱而不是數字指定了請求的 HTTP 的狀態代碼。也就是說,當狀態爲 200 的時候它是 "OK",當狀態爲 404 的時候它是 "Not Found"。和 status 屬性同樣,當 readyState 小於 3 的時候讀取這一屬性會致使一個異常。

    事件句柄:

      onreadystatechange:
      每次 readyState 屬性改變的時候調用的事件句柄函數。當 readyState 爲 3 時,它也可能調用屢次。

    方法:

      abort():
      取消當前響應,關閉鏈接而且結束任何未決的網絡活動。
      這個方法把 XMLHttpRequest 對象重置爲 readyState 爲 0 的狀態,而且取消全部未決的網絡活動。例如,若是請求用了太長時間,並且響應再也不必要的時候,能夠調用這個方法。

      getAllResponseHeaders():
      把 HTTP 響應頭部做爲未解析的字符串返回。
      若是 readyState 小於 3,這個方法返回 null。不然,它返回服務器發送的全部 HTTP 響應的頭部。頭部做爲單個的字符串返回,一行一個頭部。每行用換行符 "\r\n" 隔開。

      getResponseHeader():
      返回指定的 HTTP 響應頭部的值。其參數是要返回的 HTTP 響應頭部的名稱。可使用任何大小寫來制定這個頭部名字,和響應頭部的比較是不區分大小寫的。
      該方法的返回值是指定的 HTTP 響應頭部的值,若是沒有接收到這個頭部或者 readyState 小於 3 則爲空字符串。若是接收到多個有指定名稱的頭部,這個頭部的值被鏈接起來並返回,使用逗號和空格分隔開各個頭部的值。

      open():
      初始化 HTTP 請求參數,例如 URL 和 HTTP 方法,可是並不發送請求。

      send():
      發送 HTTP 請求,使用傳遞給 open() 方法的參數,以及傳遞給該方法的可選請求體。

      setRequestHeader():
      向一個打開但未發送的請求設置或添加一個 HTTP 請求。

    方法解析:
      XMLHttpRequest.open()
      僅僅是初始化 HTTP 請求參數
      語法
        open(method, url, async, username, password)
        
        method 參數是用於請求的 HTTP 方法。值包括 GET、POST 和 HEAD。
        url 參數是請求的主體。大多數瀏覽器實施了一個同源安全策略,而且要求這個 URL 與包含腳本的文本具備相同的主機名和端口。
        async 參數指示請求使用應該異步地執行。若是這個參數是 false,請求是同步的,後續對 send() 的調用將阻塞,直到響應徹底接收。若是這個參數是 true 或省略,請求是異步的,且一般須要一個 onreadystatechange 事件句柄。
        username 和 password 參數是可選的,爲 url 所需的受權提供認證資格。若是指定了,它們會覆蓋 url 本身指定的任何資格。
      說明
        這個方法初始化請求參數以供 send() 方法稍後使用。它把 readyState 設置爲 1,刪除以前指定的全部請求頭部,以及以前接收的全部響應頭部,而且把 responseText、responseXML、status 以及 statusText 參數設置爲它們的默認值。當 readyState 爲 0 的時候(當 XMLHttpRequest 對象剛建立或者 abort() 方法調用後)以及當 readyState 爲 4 時(已經接收響應時),調用這個方法是安全的。當針對任何其餘狀態調用的時候,open() 方法的行爲是爲指定的。
        除了保存供 send() 方法使用的請求參數,以及重置 XMLHttpRequest 對象以便複用,open() 方法沒有其餘的行爲。要特別注意,當這個方法調用的時候,實現一般不會打開一個到 Web 服務器的網絡鏈接。
        
      XMLHttpRequest.setRequestHeader()
      語法
        setRequestHeader(name, value)
        name 參數是要設置的頭部的名稱。這個參數不該該包括空白、冒號或換行。
        value 參數是頭部的值。這個參數不該該包括換行。
      說明
        setRequestHeader() 方法指定了一個 HTTP 請求的頭部,它應該包含在經過後續 send() 調用而發佈的請求中。這個方法只有當 readyState 爲 1 的時候才能調用,例如,在調用了 open() 以後,但在調用 send() 以前。
        若是帶有指定名稱的頭部已經被指定了,這個頭部的新值就是:以前指定的值,加上逗號、空白以及這個調用指定的值。
        若是 open() 調用指定了認證資格,XMLHttpRequest 自動發送一個適當的 Authorization 請求頭部。可是,你可使用 setRequestHeader() 來添加這個頭部。相似地,若是 Web 服務器已經保存了和傳遞給 open() 的 URL 相關聯的 cookie,適當的 Cookie 或 Cookie2 頭部也自動地包含到請求中。能夠經過調用 setRequestHeader() 來把這些 cookie 添加到頭部。XMLHttpRequest 也能夠爲 User-Agent 頭部提供一個默認值。若是它這麼作,你爲該頭部指定的任何值都會添加到這個默認值後面。
        有些請求頭部由 XMLHttpRequest 自動設置而不是由這個方法設置,以符合 HTTP 協議。這包括以下和代理相關的頭部:
          ·Host
          ·Connection
          ·Keep-Alive
          ·Accept-charset
          ·Accept-Encoding
          ·If-Modified-Since
          ·If-None-Match
          ·If-Range
          ·Range

      XMLHttpRequest.send()
      發送一個 HTTP 請求
      語法
        send(body)

        若是經過調用 open() 指定的 HTTP 方法是 POST 或 PUT,body 參數指定了請求體,做爲一個字符串或者 Document 對象。若是請求體不適必須的話,這個參數就爲 null。對於任何其餘方法,這個參數是不可用的,應該爲 null(有些實現不容許省略該參數)。
      說明
        這個方法致使一個 HTTP 請求發送。若是以前沒有調用 open(),或者更具體地說,若是 readyState 不是 1,send() 拋出一個異常。不然,它發送一個 HTTP 請求,該請求由如下幾部分組成:
          ·以前調用 open() 時指定的 HTTP 方法、URL 以及認證資格(若是有的話)。
          ·以前調用 setRequestHeader() 時指定的請求頭部(若是有的話)。
          ·傳遞給這個方法的 body 參數。
        一旦請求發佈了,send() 把 readyState 設置爲 2,並觸發 onreadystatechange 事件句柄。
        若是以前調用的 open() 參數 async 爲 false,這個方法會阻塞並不會返回,直到 readyState 爲 4 而且服務器的響應被徹底接收。不然,若是 async 參數爲 true,或者這個參數省略了,send() 當即返回,而且正如後面所介紹的,服務器響應將在一個後臺線程中處理。
        若是服務器響應帶有一個 HTTP 重定向,send() 方法或後臺線程自動聽從重定向。當全部的 HTTP 響應頭部已經接收,send() 或後臺線程把 readyState 設置爲 3 並觸發 onreadystatechange 事件句柄。若是響應較長,send() 或後臺線程可能在狀態 3 中觸發 onreadystatechange 事件句柄:這能夠做爲一個下載進度指示器。最後,當響應完成,send() 或後臺線程把 readyState 設置爲 4,並最後一次觸發事件句柄。

參考資料:

原生js的ajax請求

 

 

傳統方法的缺點:php

  傳統的web交互是用戶觸發一個http請求服務器,而後服務器收到以後,在作出響應到用戶,而且返回一個新的頁面,,每當服務器處理客戶端提交的請求時,客戶都只能空閒等待,而且哪怕只是一次很小的交互、只需從服務器端獲得很簡單的一個數據,都要返回一個完整的HTML頁,而用戶每次都要浪費時間和帶寬去從新讀取整個頁面。這個作法浪費了許多帶寬,因爲每次應用的交互都須要向服務器發送請求,應用的響應時間就依賴於服務器的響應時間。這致使了用戶界面的響應比本地應用慢得多。html

 

什麼是ajaxjava

  ajax的出現,恰好解決了傳統方法的缺陷。AJAX 是一種用於建立快速動態網頁的技術。經過在後臺與服務器進行少許數據交換,AJAX 可使網頁實現異步更新。這意味着能夠在不從新加載整個網頁的狀況下,對網頁的某部分進行更新。web

XMLHttpRequest 對象ajax

  XMLHttpRequest對象是ajax的基礎,XMLHttpRequest 用於在後臺與服務器交換數據。這意味着能夠在不從新加載整個網頁的狀況下,對網頁的某部分進行更新。目前全部瀏覽器都支持XMLHttpRequestapi

 

方    法 描    述
abort() 中止當前請求 
getAllResponseHeaders() 把HTTP請求的全部響應首部做爲鍵/值對返回
getResponseHeader("header") 返回指定首部的串值
open("method","URL",[asyncFlag],["userName"],["password"])  創建對服務器的調用。method參數能夠是GET、POST或PUT。url參數能夠是相對URL或絕對URL。這個方法還包括3個可選的參數,是否異步,用戶名,密碼
send(content) 向服務器發送請求
setRequestHeader("header", "value") 把指定首部設置爲所提供的值。在設置任何首部以前必須先調用open()。設置header並和請求一塊兒發送 ('post'方法必定要 )


五步使用法:
瀏覽器

  1.建立XMLHTTPRequest對象安全

  2.使用open方法設置和服務器的交互信息服務器

  3.設置發送的數據,開始和服務器端交互

  4.註冊事件

  5.更新界面

下面給你們列出get請求和post請求的例子

get請求:

//步驟一:建立異步對象
var ajax = new XMLHttpRequest();
//步驟二:設置請求的url參數,參數一是請求的類型,參數二是請求的url,能夠帶參數,動態的傳遞參數starName到服務端
ajax.open('get','getStar.php?starName='+name);
//步驟三:發送請求
ajax.send();
//步驟四:註冊事件 onreadystatechange 狀態改變就會調用
ajax.onreadystatechange = function () {
if (ajax.readyState==4 &&ajax.status==200) { //步驟五 若是可以進到這個判斷 說明 數據 完美的回來了,而且請求的頁面是存在的
  }    console.log(ajax.responseText);//輸入相應的內容
}

 post請求:

//建立異步對象  
var xhr = new XMLHttpRequest();
//設置請求的類型及url
//post請求必定要添加請求頭才行否則會報錯
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
 xhr.open('post', '02.post.php' );
//發送請求
xhr.send('name=fox&age=18');
xhr.onreadystatechange = function () {
    // 這步爲判斷服務器是否正確響應
  if (xhr.readyState == 4 && xhr.status == 200) {
    console.log(xhr.responseText);
  } 
};

爲了方便使用,咱們能夠把他封裝進方法裏面,要用的時候,直接調用就行了

function ajax_method(url,data,method,success) {
    // 異步對象
    var ajax = new XMLHttpRequest();

    // get 跟post  須要分別寫不一樣的代碼
    if (method=='get') {
        // get請求
        if (data) {
            // 若是有值
            url+='?';
            url+=data;
        }else{

        }
        // 設置 方法 以及 url
        ajax.open(method,url);

        // send便可
        ajax.send();
    }else{
        // post請求
        // post請求 url 是不須要改變
        ajax.open(method,url);

        // 須要設置請求報文
        ajax.setRequestHeader("Content-type","application/x-www-form-urlencoded");

        // 判斷data send發送數據
        if (data) {
            // 若是有值 從send發送
            ajax.send(data);
        }else{
            // 木有值 直接發送便可
            ajax.send();
        }
    }

    // 註冊事件
    ajax.onreadystatechange = function () {
        // 在事件中 獲取數據 並修改界面顯示
        if (ajax.readyState==4&&ajax.status==200) {
            // console.log(ajax.responseText);

            // 將 數據 讓 外面可使用
            // return ajax.responseText;

            // 當 onreadystatechange 調用時 說明 數據回來了
            // ajax.responseText;

            // 若是說 外面能夠傳入一個 function 做爲參數 success
            success(ajax.responseText);
        }
    }

}
相關文章
相關標籤/搜索