ajax技術詳解,封裝一個原生的ajax請求
一、Ajax 概述
Ajax 是
Asynchronous Javascript And XML
的簡寫- Ajax是一門技術,並不是一門語言
- 使用XHTML+CSS來標準化呈現
- 使用XML和XSLT進行數據交換及相關操作
- 使用XMLHttpRequest對象與Web服務器進行異步數據通信
- 使用Javascript操作Document Object Model進行動態顯示及交互
- 使用JavaScript綁定和處理所有數據
- 優點:
- 頁面局部刷新:減少用戶等待時間,提高用戶體驗
- 與服務器異步通信:不需要打斷用戶的操作,具有更迅速的相應能力
- 按需獲取數據,節約帶寬
- 缺點:
- 破壞了瀏覽器的後退機制
- 不利於搜索引擎優化;解決方案:
- 安全問題:Ajax技術就如同對企業數據建立了一個直接通道,這使得開發者在不經意間會暴露比以前更多的數據和服務器邏輯
- 破壞了瀏覽器的後退機制
- 核心:
- 組成:JavaScript、XMLHTTPRequest、DOM對象
- 通過XmlHttpRequest對象來向服務器發異步請求,從服務器獲得數據,然後用JavaScript來操作DOM而更新頁面
- 工作原理:
相當於在用戶和服務器之間加了一個中間層(ajax引擎),異步請求數據(使用戶操作 與 服務器響應異步化)
並不是所有的用戶請求都提交給服務器,像—些數據驗證(比如判斷用戶是否輸入了數據)和數據處理(比如判斷用戶輸入數據是否是數字)等都交給Ajax引擎自己來做, 只有確定需要從服務器讀取新數據時再由Ajax引擎代為向服務器提交請求
- 對比:
傳統的JS獲取數據:用戶每觸發一個 Http 請求,都需要空閑等待相應,服務器會返回一個完整的 HTML 頁面,每一次數據交互,都是一個新的頁面;即使是一次很小的交互,用戶也需要等待服務器相應 及 完整的 HTML 頁面;缺點:浪費帶寬、應用的響應時間依賴於服務器的響應時間
Ajax 突出之處:Ajax 在 Http 協議的基礎上,以異步的方式與服務器進行通信;可簡單理解為:向服務器請求數據,不用刷新頁面(頁面局部更新),這樣極大的提升了 整體執行效率 及 用戶體驗
二、Ajax 的核心對象
1. XMLHtttpRequest對象 是Ajax技術 的核心
Javascript通過XMLHttpRequest對象直接與服務器進行交互( 請求數據,獲取數據 )
XMLHtttpRequest對象,簡稱XHR對象,是Ajax技術 的核心,即 Ajax技術的引擎
XMLHtttpRequest對象 作為瀏覽器的內置對象,來實現發送、接收 HTTP請求 與 響應信息
2. XHR對象 的屬性
readyState:返回 請求的狀態(數字格式)
- 值有 5種,如下:
狀態 | 名稱 | 描述 |
---|---|---|
0 | Uninitialized | 初始化狀態:XMLHttpRequest 對象已創建 或 已被 abort() 方法重置 |
1 | Open | 請求還沒有被發送:open() 方法已調用,但是 send() 方法未調用。 |
2 | Sent | 未接收到響應:Send() 方法已調用,HTTP 請求已發送到 Web 服務器 |
3 | Receiving | 所有響應頭部都已經接收到 、響應體開始接收但未完成 |
4 | Loaded HTTP | 響應已經完全接收 |
responseText:返回 相應體(字符串格式)
- 此屬性表示:到目前為止接收到的相應體(不含頭部)
- 若沒有接收到數據,則返回空字符串
- readyState 值小於3時,這個屬性的值肯定是空字符串
- readyState 值為3時,這是屬性的值 可能是整個相應體,也可能是部分相應體
responseXML:返回的相應體(xml格式)
- 此屬性表示:到目前為止接收到的相應體(不含頭部)
status:由服務器返回的 HTTP 狀態碼(數字格式)
當 readyState 小於 3 的時候讀取這一屬性會導致一個異常
- 常見狀態碼如下:
- 200:請求成功
- 404:沒有發現文件、查詢或URl
- 400~499:客戶端問題
- 500 :服務端問題
statusText:由服務器返回的 HTTP 狀態(詳細描述)
3. XHR對象 的方法
open( ) 初始化HTTP請求,但不發送請求
- 語法:
open(method, url, async, username, password)
method
請求方式: GET、POST 、HEADurl
請求地址:同源策略async
是否異步請求:默認值為 true(可選參數);如果這個參數是 false,請求是同步的,後續對 send() 的調用將阻塞,直到響應完全接收username
、password
:為 url 所需的授權提供認證資格(可選,一般不寫)
- 作用:
把
readyState
設置為 1- 保存供
send()
方法使用的請求參數,重置 XMLHttpRequest 對象,以便復用刪除之前的請求頭、接收到的響應頭
將相應體、相應狀態碼設為默認值
send( ) 發送 HTTP 請求(會打開一個Web 服務器的網絡連接)
- 語法:
send(body)
body
請求體:get請求時 body 為null
;post請求時 body 為 請求體(一個字符串 或 對象),參數 body 應該由 以下幾部分組成:- 之前調用 open( ) 時指定的 HTTP 方法、URL 以及認證資格(如果有的話)
- 之前調用 setRequestHeader( ) 時指定的請求頭部(如果有的話)
- 傳遞給這個方法的 body 參數
- 作用:
把 readyState 設置成2,並 打開一個 Web 服務器的網絡連接
接受部分相應後,
send()
或 後臺線程 把 readyState 設置為 3接受全部相應後,
send()
或 後臺線程 把 readyState 設置為 4
- 特殊情況:
如果
readyState
不是1(也就是沒調用open( )
方法),會拋出異常如果
open()
參數 async 為false
,send( )
方法會阻塞 並不會返回,直到 readyState 為 4 並且服務器的響應被完全接收才返回
setRequestHeader() 設置請求頭
- 語法:
setRequestHeader(name, value)
name
頭部的名稱:這個參數不應該包括空白、冒號或換行value
頭部的值:這個參數不應該包括換行
- 請求頭中包含:
- Host
- Connection
- Keep-Alive
- Accept-charset
- Accept-Encoding
- If-Modified-Since
- If-None-Match
- If-Range
- Range
getResponseHeader() 獲取指定請求頭
- 語法:
getResponseHeader(name)
getAllResponseHeaders(); 獲取所有請求頭
- 語法:
getAllResponseHeaders( )
4. XHR對象 的事件
onreadystatechange readyState 改變時 會觸發 此事件
三、封裝一個原生的 Ajax
<script>
ajax({
url: "./TestXHR.aspx", //請求地址
type: "POST", //請求方式
data: {name: "super", age: 20}, //請求參數
dataType: "json",
success: function (response, xml) {
// 此處放成功後執行的代碼
},
fail: function (status) {
// 此處放失敗後執行的代碼
}
});
function ajax(options) {
options = options || {};
options.type = (options.type || "GET").toUpperCase();
options.dataType = options.dataType || "json";
var params = formatParams(options.data);
//01 創建 對象
if (window.XMLHttpRequest) {
var xhr = new XMLHttpRequest();
} else { //IE6及其以下版本瀏覽器
var xhr = new ActiveXObject(‘Microsoft.XMLHTTP‘);
}
//03 接收響應
// 監聽狀態改變
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
var status = xhr.status;
if (status >= 200 && status < 300) {
options.success && options.success(xhr.responseText, xhr.responseXML);
} else {
options.fail && options.fail(status);
}
}
}
//02 發送請求
if (options.type == "GET") {
xhr.open("GET", options.url + "?" + params, true);
xhr.send(null);
} else if (options.type == "POST") {
// 將請求數據 放到 請求主體中,並沒有發送
xhr.open("POST", options.url, true);
//設置表單提交時的內容類型
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// 發送請求
xhr.send(params);
}
}
</script>
ajax技術詳解,封裝一個原生的ajax請求