最近空閒時間,有朋友問我關於Ajax的工做原理,在這裏我結合本身的工做經驗和網上大佬的經驗作一個總結,若有不足,請各位業內大佬指正ajax
在咱們瞭解Ajax以前,咱們先來了解一下Javascript的執行原理:小程序
Javascript語言的執行環境是"單線程"(single thread),所謂的「單線程」(參考https://blog.csdn.net/baidu_24024601/article/details/51861792)也就是說,就是指一次只能完成一件任務。若是有多個任務,就必須排隊,前面一個任務完成,再執行後面一個任務,以此類推。瞭解了Javascript的執行原理之後,咱們再來看看Ajax。瀏覽器
一、什麼是Ajax?安全
AJAX全稱爲「Asynchronous JavaScript and XML」(異步JavaScript和XML),是一種建立交互式網頁應用的網頁開發技術,經過在後臺與服務器進行少許數據交換,AJAX 可使網頁實現異步更新。這意味着能夠在不從新加載整個網頁的狀況下,對網頁的某部分進行更新。 服務器
二、爲何要使用Ajax?網絡
這兒咱們能夠說到Ajax的優勢之一:它能夠在不刷新整個頁面的狀況下與服務器通訊保持原有頁面狀態,說的簡單易懂一點。舉個例子:在咱們瀏覽網頁的時候會有兩種狀況app
1.點擊連接,頁面白屏,等待跳轉到另外一個頁面。異步
2.頁面不刷新,局部出現新內容得到更好的用戶體驗。async
三、工做原理:函數
咱們先經過一張圖片來大體的瞭解一下Ajax向服務器請求數據的過程。
有人會問,圖片中的「XHR」是什麼東東,別急,咱們慢慢來
所謂的「XHR」(瀏覽器內置對象」XMLHttpRequest 」),也就是Ajax功能實現所依賴的對象,AJAX就是經過瀏覽器的內置對象XHMHttpResquest來發送異步請求的,異步請求不會妨礙客戶端的任何操做。
異步:
XHR至關因而一個通訊兵,來負責客戶端與服務器之間的通訊傳輸。舉個形象生動的例子:
要打仗了,前方陣地(客服端)不可能只等着通訊兵(XHR)傳遞消息其餘什麼也不幹吧,因此前方陣地還在幹着本身的事情而後派通訊兵去請求後方指揮部(服務器)的命令,指揮部下達命令指揮,通訊兵再把命令傳到前方陣地,而後前方陣地再執行命令相關的操做(客戶端把數據渲染到頁面),這也就是Ajax的異步原理。
再來講說同步:
所謂的同步就是前方陣地和通訊兵一塊兒去向服務器請求數據,直到通訊兵請求到數據,我纔開始渲染頁面,在請求的過程當中頁面一直是白屏等待的。
AJAX既然是經過瀏覽器的內置對象XMLHttpRequest來處理異步請求的那咱們先來了解下他又哪些方法和屬性:
注:寫在這裏的爲必選參數或者常常用到的可選參數
方法:
1、open();
解釋:發送請求的頁面在不刷新的狀況能將參數傳給一個服務器進行處理, 這個方法就是將這些個參數傳送過去
參數:
1, method:用於指定請求的類型 "GET"或者"POST"
2, url:用於請求的地址, 可相對可絕對
3, asyncFlag:指定請求方式爲同步仍是異步, true爲異步, false爲同步
2、send();
解釋:這個東西就是將一些參數以鍵值對的方式傳送給服務器, 異步的話將當即返回服務器的響應, 作到不刷新頁面進行數據處理就是用來發送參數的, GET方法下能夠在url的後面寫上參數的值, POST方法下只能在send()方法裏面寫上參數的鍵值對
3、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 // 取對象的值有兩種方式,一、"."" 二、"[]" 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. 自動更新頁面