原文(個人GitHub):https://github.com/liangfengbo/frontend-ability/issues/1javascript
1. w3chool官網:Ajax 是一種在無需從新加載整個網頁的狀況下,可以更新部分網頁的技術。 2. 個人理解:無須刷新頁面便可從服務器取得數據的技術。
Ajax的工做原理至關於在用戶和服務器之間加了—箇中間層,使用戶操做與服務器響應異步化。並非全部的用戶請求都提交給服務器,像—些數據驗證和數據處理等都交給Ajax引擎本身來作, 只有肯定須要從服務器讀取新數據時再由Ajax引擎代爲向服務器提交請求。html
Ajax技術的核心是XMLHttpRequest對象。
new ActiveXObject(versions); new XMLHttpRequest();
方法 | 描述 |
---|---|
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'方法必定要 ) |
屬性 | 描述 |
---|---|
onreadystatechange | 狀態改變的事件觸發器,每一個狀態改變時都會觸發這個事件處理器,一般會調用一個JavaScript函數 |
readyState | 請求的狀態。有5個可取值:0 = 未初始化,1 = 正在加載,2 = 已加載,3 = 交互中,4 = 完成 |
responseText | 服務器的響應,返回數據的文本。 |
responseXML | 服務器的響應,返回數據的兼容DOM的XML文檔對象 ,這個對象能夠解析爲一個DOM對象。 |
responseBody | 服務器返回的主題(非文本格式) |
responseStream | 服務器返回的數據流 |
status | 服務器的HTTP狀態碼(如:404 = "文件末找到" 、200 ="成功" ,等等) |
statusText | 服務器返回的狀態文本信息 ,HTTP狀態碼的相應文本(OK或Not Found(未找到)等等) |
事件 | 描述 |
---|---|
loadstart | 在接收到響應數據的第一個字節時觸發。 |
progress | 在接收響應期間持續不斷地觸發。 |
error | 在請求發生錯誤時觸發。 |
abort | 在由於調用abort()方法而終止鏈接時觸發。 |
load | 在接收到完整的響應數據時觸發。 |
loadend | 在通訊完成或者觸發error、abort或load事件後觸發。 |
/** * 建立Ajax * @param options */ function Ajax(options) { // 新建一個對象,用途接受XHR對象 var xhr = null; // 第一步建立XMLHttpRequest對象 || 同時兼任IE // 首先檢測原生XHR對象是否存在,若是存在則返回它的新實例 if (typeof XMLHttpRequest != "undefined") { xhr = new XMLHttpRequest(); // 而後若是原生對象不存在,則檢測ActiveX對象 } else if (typeof ActiveXObject != "undefined") { // 若是存在,則建立他的對象,但這個對象須要一個傳入參數,以下: if (typeof arguments.callee.activeXString != 'string') { // 對象版本 var versions = [ 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.7.0', 'Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML.XMLHTTP' ], i, len; for (i = 0, len = versions.length; i < len; i++) { try { // 須要versions數組中的某個項,數組的7個項分別對應7個版本. new ActiveXObject(versions[i]); // arguments是javascript函數的內置對象,表明傳入參數的集合, // callee就表明對象自己即new createXHR arguments.callee.activeXString = versions[i]; break; } catch (e) { // 跳過 } } } // 直到循環建立成功爲止,而後給本身添加一個屬性叫activeXString xhr = new ActiveXObject(arguments.callee.activeXString); } else { // 若是這兩種對象都不存在,就拋出一個錯誤 throw new Error('No XHR object available'); } /** ** options形參解析: * data 發送的參數,格式爲對象類型 * url 發送請求的url,服務器地址(api) * async 否爲異步請求,true爲異步的,false爲同步的 * method http鏈接的方式,包括POST和GET兩種方式 */ options = options || {}; options.success = options.success || function () { }; options.fail = options.fail || function () { }; var data = options.data, url = options.url, async = options.async === undefined ? true : options.async, method = options.method.toUpperCase(), dataArr = []; // 遍歷參數 for (var k in data) { dataArr.push(k + '=' + data[k]); } // GET請求 if (method === 'GET') { url = url + '?' + dataArr.join('&'); xhr.open(method, url.replace(/\?$/g, ''), async); xhr.send(); } // POST請求 if (method === 'POST') { xhr.open(method, url, async); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.send(dataArr.join('&')); } // 響應接收完畢後將觸發load事件 xhr.onload = function () { /** * XHR對象的readyState屬性 * 0:未初始化。還沒有調用open()方法。 * 1:啓動。已經調用open()方法,但還沒有調用send()方法。 * 2:發送。已經調用send()方法,但還沒有接收到響應。 * 3:接收。已經接收到部分響應數據。 * 4:完成。已經接收到所有響應數據,並且已經能夠在客戶端使用了。 */ if (xhr.readyState == 4) { // 獲得響應 if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { // 處理成功數據 var res; if (options.success && options.success instanceof Function) { res = xhr.responseText; if (typeof res === 'string') { res = JSON.parse(res); options.success.call(xhr, res); } } } else { // 處理錯誤數據 if (options.fail && options.fail instanceof Function) { options.fail.call(xhr, res) } } } else { // 拋出檢測XHR對象的readyState屬性 console.log('XHR was readyState:', xhr.readyState); } } }
參數 | 類型 | 描述 | 默認值 | 是否填 |
---|---|---|---|---|
url | string | 發送請求的url,服務器地址(api) | '' | 必填 |
method | string | http鏈接的方式,包括POST和GET兩種方式 | true | 選填 |
async | boolean | 是否爲異步請求,true爲異步的,false爲同步的 | true | 選填 |
data | json | 發送的參數,格式爲對象(json)類型 | null | 選填 |
success | function | 請求成功回調函數 | function () { } | 必填 |
fail | function | 請求失敗回調函數 | function () { } | 必填 |
Ajax({ url: 'http://localhost:3000/api/v1/article', method: 'GET', async: true, success: function (res) { console.log('successful', res); }, fail: function (err) { console.log('fail', err); } })
successful {code: 200, msg: "查詢文章列表成功!", data: {…}}
AJAX最大優勢就是能在不刷新整個頁面的前提下與服務器通訊維護數據。這使得Web應用程序更爲迅捷地響應用戶交互,並避免了在網絡上發送那些沒有改變的信息,減小用戶等待時間,帶來很是好的用戶體驗。前端
AJAX使用異步方式與服務器通訊,不須要打斷用戶的操做,具備更加迅速的響應能力。優化了Browser和Server之間的溝通,減小沒必要要的數據傳輸、時間及下降網絡上數據流量。java
AJAX能夠把之前一些服務器負擔的工做轉嫁到客戶端,利用客戶端閒置的能力來處理,減輕服務器和帶寬的負擔,節約空間和寬帶租用成本。而且減輕服務器的負擔,AJAX的原則是「按需取數據」,能夠最大程度的減小冗餘請求和響應對服務器形成的負擔,提高站點性能。git
AJAX基於標準化的並被普遍支持的技術,不須要下載瀏覽器插件或者小程序,但須要客戶容許JavaScript在瀏覽器上執行。隨着Ajax的成熟,一些簡化Ajax使用方法的程序庫也相繼問世。一樣,也出現了另外一種輔助程序設計的技術,爲那些不支持JavaScript的用戶提供替代功能。github
Ajax使WEB中的界面與應用分離(也能夠說是數據與呈現分離),有利於分工合做、減小非技術人員對頁面的修改形成的WEB應用程序錯誤、提升效率、也更加適用於如今的發佈系統。面試
在動態更新頁面的狀況下,用戶沒法回到前一個頁面狀態,由於瀏覽器僅能記憶歷史記錄中的靜態頁面。一個被完整讀入的頁面與一個已經被動態修改過的頁面之間的差異很是微妙;用戶一般會但願單擊後退按鈕可以取消他們的前一次操做,可是在Ajax應用程序中,這將沒法實現ajax
JAX技術給用戶帶來很好的用戶體驗的同時也對IT企業帶來了新的安全威脅,Ajax技術就如同對企業數據創建了一個直接通道。這使得開發者在不經意間會暴露比之前更多的數據和服務器邏輯。Ajax的邏輯能夠對客戶端的安全掃描技術隱藏起來,容許黑客從遠端服務器上創建新的攻擊。還有Ajax也難以免一些已知的安全弱點,諸如跨站點腳步攻擊、SQL注入攻擊和基於Credentials的安全漏洞等等數據庫
對搜索引擎的支持比較弱。若是使用不當,AJAX會增大網絡數據的流量,從而下降整個系統的性能。json
至少從目前看來,像Ajax.dll,Ajaxpro.dll這些Ajax框架是會破壞程序的異常機制的。關於這個問題,曾在開發過程當中遇到過,可是查了一下網上幾乎沒有相關的介紹。後來作了一次試驗,分別採用Ajax和傳統的form提交的模式來刪除一條數據……給咱們的調試帶來了很大的困難
一些手持設備(如手機、PDA等)如今還不能很好的支持Ajax,好比說咱們在手機的瀏覽器上打開採用Ajax技術的網站時,它目前是不支持的。
Ajax並不算是一種新的技術,全稱是asychronous javascript and xml,能夠說是已有技術的組合,主要用來實現客戶端與服務器端的異步通訊效果,實現頁面的局部刷新,早期的瀏覽器並不能原生支持ajax,可使用隱藏幀(iframe)方式變相實現異步效果,後來的瀏覽器提供了對ajax的原生支持
使用ajax原生方式發送請求主要經過XMLHttpRequest(標準瀏覽器)、ActiveXObject(IE瀏覽器)對象實現異步通訊效果
基本步驟:
var xhr =null;//建立對象 if(window.XMLHttpRequest){ xhr = new XMLHttpRequest(); }else{ xhr = new ActiveXObject("Microsoft.XMLHTTP"); } xhr.open(「方式」,」地址」,」標誌位」);//初始化請求 xhr.setRequestHeader(「」,」」);//設置http頭信息 xhr.onreadystatechange =function(){}//指定回調函數 xhr.send();//發送請求
js框架(jQuery/EXTJS等)提供的ajax API對原生的ajax進行了封裝,熟悉了基礎理論,再學習別的框架就會駕輕就熟,好多都是換湯不換藥的內容
同步:阻塞的
異步:非阻塞的
理解跨域的概念:協議、域名、端口都相同才同域,不然都是跨域
出於安全考慮,服務器不容許ajax跨域獲取數據,可是能夠跨域獲取文件內容,因此基於這一點,能夠動態建立script標籤,使用標籤的src屬性訪問js文件的形式獲取js腳本,而且這個js腳本中的內容是函數調用,該函數調用的參數是服務器返回的數據,爲了獲取這裏的參數數據,須要事先在頁面中定義回調函數,在回調函數中處理服務器返回的數據,這就是解決跨域問題的主流解決方案
對於ajax請求傳遞的參數,若是是get請求方式,參數若是傳遞中文,在有些瀏覽器會亂碼,不一樣的瀏覽器對參數編碼的處理方式不一樣,因此對於get請求的參數須要使用encodeURIComponent函數對參數進行編碼處理,後臺開發語言都有相應的解碼api。對於post請求不須要進行編碼
同源策略是客戶端腳本(尤爲是Javascript)的重要的安全度量標準。它最先出自Netscape Navigator2.0,其目的是防止某個文檔或腳本從多個不一樣源裝載。所謂同源指的是:協議,域名,端口相同,同源策略是一種安全協議,指一段腳本只能讀取來自同一來源的窗口和文檔的屬性。
GET:通常用於信息獲取,使用URL傳遞參數,對所發送信息的數量也有限制,通常在2000個字符,有的瀏覽器是8000個字符
POST:通常用於修改服務器上的資源,對所發送的信息沒有限制
在如下狀況中,請使用 POST 請求:
Ajax能夠實現異步通訊效果,實現頁面局部刷新,帶來更好的用戶體驗;按需獲取數據,節約帶寬資源;
一、ajax不支持瀏覽器back按鈕。
二、安全問題 AJAX暴露了與服務器交互的細節。
三、對搜索引擎的支持比較弱。
四、破壞了程序的異常機制。
get通常用來進行查詢操做,url地址有長度限制,請求的參數都暴露在url地址當中,若是傳遞中文參數,須要本身進行編碼操做,安全性較低。
post請求方式主要用來提交數據,沒有數據長度的限制,提交的數據內容存在於http請求體中,數據不會暴漏在url地址中。
Jsonp並非一種數據格式9,而json是一種數據格式,jsonp是用來解決跨域獲取數據的一種解決方案,具體是經過動態建立script標籤,而後經過標籤的src屬性獲取js文件中的js腳本,該腳本的內容是一個函數調用,參數就是服務器返回的數據,爲了處理這些返回的數據,須要事先在頁面定義好回調函數,本質上使用的並非ajax技術
Ajax是全稱是asynchronous JavaScript andXML,即異步JavaScript和xml,用於在Web頁面中實現異步數據交互,實現頁面局部刷新。
優勢:可使得頁面不重載所有內容的狀況下加載局部內容,下降數據傳輸量,避免用戶不斷刷新或者跳轉頁面,提升用戶體驗
缺點:對搜索引擎不友好;要實現ajax下的先後退功能成本較大;可能形成請求數的增長跨域問題限制;
JSON是一種輕量級的數據交換格式,ECMA的一個子集
優勢:輕量級、易於人的閱讀和編寫,便於機器(JavaScript)解析,支持複合數據類型(數組、對象、字符串、數字)
200 - 請求成功
301 - 資源(網頁等)被永久轉移到其它URL
404 - 請求的資源(網頁等)不存在
500 - 內部服務器錯誤
分爲4個步驟:
get通常用來進行查詢操做,url地址有長度限制,請求的參數都暴露在url地址當中,若是傳遞中文參數,須要本身進行編碼操做,安全性較低。
post請求方式主要用來提交數據,沒有數據長度的限制,提交的數據內容存在於http請求體中,數據不會暴漏在url地址中。
1八、ajax請求時,如何解釋json數據
使用eval() 或者JSON.parse() 鑑於安全性考慮,推薦使用JSON.parse()更靠譜,對數據的安全性更好。
JavaScript高級程序設計第三版
AJAX工做原理及其優缺點
Ajax原理以及優缺點
Ajax的工做原理
Ajax系列面試題總結01