AJAX
AJAX,即 Asynchronous(異步的) JavaScript and XML。
AJAX不是一門新的語言,而是對現有技術的綜合運用。
其本質是在HTTP協議的基礎上以異步的方式與服務器進行通信。
AJAX是一種用于創建快速動態網頁的技術。通過在后臺與服務器進行少量的數據交換,AJAX可以使網頁實現異步更新。即在不重載整個網頁面的情況下,對網頁的某部分進行更新。
AJAX 的好處
AJAX 可以實現異步通信效果,實現頁面局部刷新,帶來更好的用戶體驗:按需獲取數據,節約寬帶資源。
AJAX 的缺點
- AJAX 不支持瀏覽器的 back 按鈕。
- 安全問題。AJAX 暴露了與服務器交互的細節。
- 對搜索引擎的支持比較弱。
- 破壞了程序的異常機制
異步
指某段程序執行時不會阻塞其它程序執行,其表現形式為程序的執行順序,不依賴程序本身的書寫順序,相反則為同步。其優勢在于不阻塞程序的執行,從而提升整體的執行效率。
實現異步加載的方式
- defer 只支持ie
<script type="text/javascript" defer="defer"></script>
- async html5的屬性
<script type="text/javascript" src="" async="async"></script>
- 動態創建script
function loadScript(url, callback){
var script = document.createElement("script")
script.type = "text/javascript";
if (script.readyState){ //IE
script.onreadystatechange = function(){
if (script.readyState == "loaded" ||script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
} else { //Others: Firefox, Safari, Chrome, and Opera
script.onload = function(){
callback();
};
}
script.src = url;
document.body.appendChild(script);
}
- 由于javascript的動態性,還有很多異步加載的方法:XHR Injection、XHR Eval、Script In Iframe、Script defer屬性等等。
- XHR Injection(XHR 注入):通過XMLHttpRequest來獲取javascript,然后創建一個script元素插入到DOM結構中。ajax請求成功后設置script.text為請求成功后返回的responseText。
另外:實現異步編程有哪些方式。(摘自Javascript異步編程的4種方法)
- 回調函數 callback
function f1(callback){
setTimeout(function () {
//f1的任務代碼
callback();
},1000);
}
回調函數的優點是簡單,易理解和部署,缺點是不利于代碼閱讀和維護,各部分之間高度耦合,流程會很混亂,而且每個任務只能指定一個回調函數。
- 事件監聽
f1.on('done', f2);
function f1() {
setTimeout(function () {
//f1的任務代碼
f1.trigger('done');
}, 1000);
}
這種方法的優點是比較容易理解,可以綁定多個事件,每個事件可以指定多個回調函數,而且可以“去耦合”,有利于實現模塊化。缺點是整個程序都要變成事件驅動型,運行流程會變得很不清晰。
- 發布/訂閱
采用的是Ben Alman 的 Tiny Pub/Sub
jQuery.subscribe("done", f2);
function f1() {
setTimeout(function () {
//f1的任務代碼
jQuery.publish("done")
}, 1000);
}
發布/訂閱模式(public-subscribe pattern),又稱觀察者模式(observer pattern)。
f1執行完成后向信號中心發布done信號,從而引發f2的執行。
f2執,行完成后可以取消訂閱。
jQuery.unsubscribe("done", f2);
這種方法的性質和“事件監聽”類似,但是明顯優于后者。因為我們可以通過查看“消息中心”。了解存在多少信號、每個信號有多少訂閱者,從而監控程序的運行。
- Promise對象
ES6是由社區最早提出和實現,ES6將其寫進了語言標準,統一了用法,原生提供了Promise對象。
從語法上說,Promise是一個對象,可以獲取異步操作的結果,它有三種狀態。
- Pending(進行中)
- Resolved(已完成,又稱Fulfilled)
- Rejected(已失敗)
只有異步操作的結果,可以決定當前是哪一種狀態。
一旦狀態改變,就不會再變,任何時候都可以得到這個結果。Promise對象的狀態改變,只有兩種可能: - 從 Pending 變為 Resolved。
- 從 Pending 變為 Rejected。
var promise = new Promise(function(resolve, reject) {
if (/* 異步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
promise.then(function(value) {
// success
}, function(error) {
// failure
});
扯遠了...
同步異步的區別
- 同步:阻塞的
瀏覽器向服務器請求數據,服務器比較忙,瀏覽器一直等著(頁面白屏),直到服務器返回數據,瀏覽器才能顯示頁面。 - 異步:非阻塞的
瀏覽器向服務器請求數據,服務器比較忙,瀏覽器可以自如的干原來的事情(顯示頁面),服務器返回數據的時候通知瀏覽器一聲,瀏覽器把返回的數據再渲染到頁面,局部更新。
XMLhttpRequest
XMLhttpRequest可以以異步方式的處理程序。
瀏覽器內建對象,用于在后臺與服務器通信(交換數據),由此我們便可實現對網頁的部分更新,而不是刷新整個頁面。
一個基本的例子:
//實例化
var xhr = new XMLHttpRequest();
//發起一個http請求
xhr.open('get', 'index.php');
xhr.send(null);
//接收服務器響應
xhr.onreadystatechange = function () {
if(xhr.readyState == 4 && xhr.status == 200) {
var result = document.querySelector('.result');
result.innerHTML = xhr.responseText
}
}
請求
XMLHttpRequest 本質基于 HTTP 協議實現通信。HTTP 請求 3 個組成部分與 XMLHttpRequest 方法的對應關系:
- 請求行
xhr.open('get', 'index.php')
- 請求頭(get 請求可以不設置)
xhr.setRequestHeader('Content-Type', 'text/html');
- 請求主體
xhr.send(null);
響應
HTTP響應 3 個組成部分與 XMLHttpRequest 方法或屬性的對應關系。
由于服務器做出響應需要時間(比如網速慢等原因),所以我們需要監聽服務器響應的狀態,然后才能進行處理。
xhr.onreadystatechange = function () {
if(xhr.readyState == 4 && xhr.status == 200) {
var result = document.querySelector('.result');
result.innerHTML = xhr.responseText;
}
}
onreadystatechange 是 Javascript 的事件的一種,其意義在于監聽 XMLHttpRequest 的狀態。
- 獲取狀態行(包括狀態碼和狀態信息)
xhr.status
xhr.statusText
- 獲取響應頭
//獲取指定頭信息
xhr.getResponseHeader('Content-Type');
//獲取所有響應頭信息
hr.getAllResponseHeaders();
- 響應主體
xhr.responseText;
xhr.responseXML;
我們需要檢測并判斷響應頭的 MIME 類型后確定使用 request.responseText 或者 request.responseXML.
創建一個 ajax
var xhr = null;//創建對象
if (window.XMLHttpRequest) {
xhr = new XHLHttpRequest();
}else {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open("方式", "地址", "標志位");//初始化請求
xhr.setRequestHeader("","")//設置相應頭信息
xhr.onreadystatechange = function () {}//指定回調函數
xhr.send();//發送請求
簡述ajax的過程
- 創建 XMLHttpRequest 對象,也就是創建一個異步調用對象。
- 創建一個新的 HTTP 請求,并指定該 HTTP 請求的方法、URL 及驗證信息。
- 設置響應 HTTP 請求狀態變化的函數。
- 發送 HTTP 請求
- 獲取異步調用返回的數據
- 使用 JavaScript 和 DOM 實現局部刷新
get 和 post 請求方式的差異
- get 請求沒有請求主體,使用 xhr.send(null)。
- get 可以通過在請求 URL 上添加請求參數。
- post 可以通過 xhr.send('name=i&age=10')。
- post 需要設置請求頭 xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
- get 效率更好(應用比較多)。
- get 大小限制約 4K,post則沒有限制。
get 和 post 的區別,什么時候使用 post 請求
- get:一般用于信息獲取,使用 URL 傳遞參數,對所發信息的數量也有限制,一般在 2000 個字符,有的瀏覽器是 8000 個字符。
- 一般用于修改服務器上的資源,對所發送的信息沒有限制。
以下情況中,使用post 請求:- 無法使用緩存文件(更新服務器上的文件或數據庫)
- 向服務器發送大量數據(post 沒有數據量限制)
- 發送包含未知字符的用戶輸入時,post 比 get 更穩定也更可靠。
jquery 中的 ajax
- $.ajax({}) 可配置方式發起 Ajax 請求。
- $.get() 以 get 方式發起 Ajax 請求。
- $.post() 以 post 方式發起ajax請求。
- $('form').serialize() 序列化表單(即格式化 key=val&key=val)
- url 接口地址
- type 請求方式
- timeout 請求超時
- dataType 服務器返回格式
- data 發送請求數據
- beforeSend:function(){} 請求發起前調用
- success 成功響應后調用
- error 錯誤響應時調用
- complete 響應完成時調用(包括成功和失敗)
最后
忽然發現已經忘了 ajax 的一些理論基礎方面的知識了... 面試忽然問起,恩,懵住了... 所以學習嘛,還是要時常復習。