最近空閑時間,有朋友問我關於Ajax的工作原理,在這里我結合自己的工作經驗和網上大佬的經驗做一個總結,如有不足,請各位業內大佬指正
在我們了解Ajax之前,我們先來了解一下Javascript的執行原理:
Javascript語言的執行環境是"單線程"(single thread),所謂的“單線程”(參考https://blog.csdn.net/baidu_24024601/article/details/51861792)也就是說,就是指一次只能完成一件任務。如果有多個任務,就必須排隊,前面一個任務完成,再執行后面一個任務,以此類推。了解了Javascript的執行原理以后,我們再來看看Ajax。
1、什么是Ajax?
AJAX全稱為“Asynchronous JavaScript and XML”(異步JavaScript和XML),是一種創建交互式網頁應用的網頁開發技術,通過在后台與服務器進行少量數據交換,AJAX 可以使網頁實現異步更新。這意味着可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。
2、為什么要使用Ajax?
這兒我們可以說到Ajax的優點之一:它可以在不刷新整個頁面的情況下與服務器通信保持原有頁面狀態,說的簡單易懂一點。舉個例子:在我們瀏覽網頁的時候會有兩種情況
1.點擊鏈接,頁面白屏,等待跳轉到另一個頁面。
2.頁面不刷新,局部出現新內容獲得更好的用戶體驗。
3、工作原理:
我們先通過一張圖片來大致的了解一下Ajax向服務器請求數據的過程。
有人會問,圖片中的“XHR”是什么東東,別急,我們慢慢來
所謂的“XHR”(瀏覽器內置對象”XMLHttpRequest ”),也就是Ajax功能實現所依賴的對象,AJAX就是通過瀏覽器的內置對象XHMHttpResquest來發送異步請求的,異步請求不會妨礙客戶端的任何操作。
異步:
XHR相當於是一個通信兵,來負責客戶端與服務器之間的通信傳輸。舉個形象生動的例子:
要打仗了,前方陣地(客服端)不可能只等着通信兵(XHR)傳遞消息其他什么也不干吧,所以前方陣地還在干着自己的事情然后派通信兵去請求后方指揮部(服務器)的命令,指揮部下達命令指揮,通信兵再把命令傳到前方陣地,然后前方陣地再執行命令相關的操作(客戶端把數據渲染到頁面),這也就是Ajax的異步原理。
再來說說同步:
所謂的同步就是前方陣地和通信兵一起去向服務器請求數據,直到通信兵請求到數據,我才開始渲染頁面,在請求的過程中頁面一直是白屏等待的。
AJAX既然是通過瀏覽器的內置對象XMLHttpRequest來處理異步請求的那我們先來了解下他又哪些方法和屬性:
注:寫在這里的為必選參數或者經常用到的可選參數
方法:
一、open();
解釋:發送請求的頁面在不刷新的情況能將參數傳給一個服務器進行處理, 這個方法就是將這些個參數傳送過去
參數:
1, method:用於指定請求的類型 "GET"或者"POST"
2, url:用於請求的地址, 可相對可絕對
3, asyncFlag:指定請求方式為同步還是異步, true為異步, false為同步
二、send();
解釋:這個東西就是將一些參數以鍵值對的方式傳送給服務器, 異步的話將立即返回服務器的響應, 做到不刷新頁面進行數據處理就是用來發送參數的, GET方法下可以在url的后面寫上參數的值, POST方法下只能在send()方法里面寫上參數的鍵值對
三、setRequestHeader("header","value")
解釋:用於為請求的Http頭設置值
四, getResponseHeader("headerLabel");
解釋: 返回設置的Http頭信息
五, abort();
個人理解: 使用了這個請求之后會直接停止getResult的回調函數, 讓readyState屬性的返回值直接為0
六, getAllResponseHeaders();
解釋:以字符串的形式返回完整的字符串信息
屬性:
一, onreadystatechange
解釋: 用於指定狀態改變時所觸發的事件處理器(在設置回調函數的時候經常用到, 所有的狀態改變的時候都會觸發這個事件處理器)
二, readyState
解釋: 用於獲取請求的狀態( 通過返回的代碼是多少來判斷當前的狀態是什么情況)
返回值有:0: 未初始化; 1: 正在加載; 2:已加載; 3:交互中; 4:完成
三, responseText
書上解釋: 獲取服務器的響應, 表示為字符串(response.getWrite().append("");將這個語句的內容返回到用戶頁面)
四, responseXML
解釋: 用於獲取服務器的響應, 表示為字符串
五, status
返回Http狀態碼——200:表示成功; 202:表示請求被接受, 但尚未成功; 400:錯誤的請求; 404:文件未找到; 500:內部服務器錯誤
六, statusText
返回Http狀態碼的文本信息
下面讓我們通過一段代碼實例來了解一下Ajax的使用方法:
1 /** 2 * ajax參數: 3 * ajax({ 4 * method:post,get, 5 * url, 6 * param:參數, 7 * callback:回調函數 8 * }) 9 * 10 */ 11 var test = (function () { //函數自執行 test存放返回的值,作為全局變量 12 13 // ajax創建兼容封裝 14 function getXlmHttp(obj) { 15 var xmlHttp; 16 if (window.XMLHttpRequest) { //兼容DOM 17 xmlHttp = new XMLHttpRequest(); 18 } else if (window.ActiveXObject) { //兼容IE 19 xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); 20 } 21 return xmlHttp; 22 23 } 24 25 // ajax get請求 26 function getAjax(obj) { 27 var xmlHttp = getXlmHttp(); 28 xmlHttp.onreadystatechange = function () { 29 if (xmlHttp.readyState == 4 && xmlHttp.status == 200) { 30 console.log(xmlHttp.responseText); 31 obj.callback(xmlHttp); 32 } 33 } 34 // var obj = { "username": '張三', "password": "123" } 35 // 取對象的值有兩種方式,1、"."" 2、"[]" 36 // 運算符要求是標識符,不能使變量, 37 var str; 38 for (key in obj.param) { 39 str = "key" + "=" + obj.param[key] + "&"; 40 } 41 if (str.length > 0) { 42 str.url = obj.url + "?" + str; 43 } 44 xmlHttp.open(obj.method, obj.url) 45 xmlHttp.send(null) 46 } 47 48 // ajax post請求 49 // var obj = { "username": '張三', "password": "123" } 50 function postAjax(obj) { 51 var xmlHttp = getXlmHttp(); 52 xmlHttp.onreadystatechange = function () { 53 if (xmlHttp.readyState == 4 && xmlHttp.status == 200) { 54 console.log(xmlHttp.responseText); 55 obj.callback(xmlHttp); 56 } 57 } 58 var str; 59 for (key in obj.param) { 60 str = "key" + "=" + obj.param[key] + "&"; 61 } 62 if (str.length > 0) { 63 str.url = obj.url + "?" + str; 64 } 65 xmlHttp.open(obj.method, obj.url); 66 xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 67 xmlHttp.send(str); 68 } 69 70 // 調用請求方式封裝 71 function ajax(obj) { 72 if (obj.method = "post") { 73 postAjax(obj); 74 } 75 else if (obj.method = "get") { 76 getAjax(obj) 77 } 78 } 79 80 // ajax Json封裝 81 function getJson(obj) { 82 obj.callback = function (xmlHttp) { 83 var obj = JSON.parse(xmlHttp.responseText); 84 obj.callback(obj); 85 } 86 getAjax(obj); 87 } 88 return { "getAjax": getAjax, "postAjax": postAjax, "getJson": getJson, "ajax": ajax } //返回值 89 })(); 90 91 test.getAjax() //調用封裝的函數
優點:
1.最大的優點就是頁面無需刷新,在頁面內與服務器通信,非常好的用戶體驗。
2.使用異步的方式與服務器通信,不需要中斷操作。
3.可以把以前服務器負擔的工作轉嫁給客戶端,減輕服務器和帶寬,可以最大程度減少冗余請求。
4.基於標准化的並被廣泛支持的技術,不需要下載插件或者小程序。
缺點:
1.AJAX干掉了Back和History功能,即對瀏覽器機制的破壞。
在動態更新頁面的情況下,用戶無法回到前一個頁面狀態,因為瀏覽器僅能記憶歷史記錄中的靜態頁面。一個被完整讀入的頁面與一個已經被動態修改過的頁面之間的差別非常微妙;用戶通常會希望單擊后退按鈕能夠取消他們的前一次操作,但是在Ajax應用程序中,這將無法實現。
2.安全問題技術同時也對IT企業帶來了新的安全威脅,ajax技術就如同對企業數據建立了一個直接通道。這使得開發者在不經意間會暴露比以前更多的數據和服務器邏輯。ajax的邏輯可以對客戶端的安全掃描技術隱藏起來,允許黑客從遠端服務器上建立新的攻擊。還有ajax也難以避免一些已知的安全弱點,諸如跨站點腳步攻擊、SQL注入攻擊和基於credentials的安全漏洞等。
3.對搜索引擎的支持比較弱。如果使用不當,AJAX會增大網絡數據的流量,從而降低整個系統的性能。
應用場景:
場景 1. 數據驗證
場景 2. 按需取數據
場景 3. 自動更新頁面