文章目錄
- Ajax 概述
- Ajax 物件
- Get、Post請求方式的底層實作
- Ajax 函式的封裝
Ajax 概述
傳統網站中存在的問題:
- 網速慢的情況下,頁面加載時間長,用戶只能等待
- 表單提交后,如果一項內容不合格,需要重新填寫所有表單內容
- 頁面跳轉,重新加載頁面,造成資源浪費,增加用戶等待時間
Ajax: Asynchronous JavaScript And XML,異步JavaScript和XML技術
- 描述:不是一門新的語言或技術,是由JavaScript、XML、DOM、CSS等多種已有技術組合而成的一種瀏覽器端技術,
- 功能:用于實作與服務器進行異步互動的功能,實作頁面無重繪更新資料,提高用戶瀏覽網站應用的體驗
Ajax 詳解:
- AJAX提供與服務器異步通信的能力,可以在Web頁面觸發的JavaScript事件中向服務器發出異步請求,執行更新或查詢資料庫
- AJAX的核心是JavaScript物件 XMLHttpRequest,該物件在IE5中首次引入,使用戶通過JavaScript向服務器提出請求并處理回應,而不阻塞用戶
- 當Web服務器的回應回傳時,使用JavaScript回呼函式和CSS來相應地更新頁面的區域內容,而不是重繪整個頁面
- 在頁面與服務器互動的程序中不中斷用戶操作,用戶甚至察覺不到瀏覽器正在與服務器通信

Ajax 應用場景:
- 頁面上拉加載更多資料
- 串列資料無重繪分頁
- 表單項離開焦點資料驗證
- 搜索框提示文字下拉串列
Ajax 運行原理:
Ajax 相當于瀏覽器發送請求與接收回應的代理人,以實作在不影響用戶瀏覽頁面的情況下,區域更新頁面資料,從而提高用戶體驗

Ajax 執行機制:

Ajax 物件
XMLHttpRequest 物件:
- XMLHttpRequest 物件最初是在IE5中以ActiveX組件的形式實作的,但只能在IE瀏覽器中使用,其后在Mozilla、Safari等瀏覽器中相繼實作,才成為事實上的標準,目前FireFox、Safari、Opera和IE7中都以類似的方式實作了 XMLHttpRequest物件
- 由于XMLHttpRequest不是w3c的標準,可以采用多種方法創建XMLHttpRequest物件,在使用XMLHttpRequest物件發生請求和處理之前,必須首先使用 JavaScript獲得XMLHttpRequest物件
XMLHttpRequest方法:
| 方法 | 描述 |
|---|---|
| abort() | 停止當前請求 |
| getAllResponseHeaders() | 將所有HTTP請求的回應首部作為鍵/值對回傳 |
| getResponseHeader(‘header’) | 回傳指定回應的首部資訊 |
| open(‘method’,‘URL’) | 建立對服務器的呼叫,方法通常是post或get,URL可以絕對路徑或相對路徑 |
| send(content) | 向服務器發送請求,引數可以是null |
| setRequestHeader(‘header’, ‘value’) | 設定HTTP請求的首部資訊,可以向服務器傳遞引數,這個方法必須在open之后呼叫 |
XMLHttpRequest屬性:
| 屬性 | 描述 |
|---|---|
| Onreadystatechange | 每次狀態改變所觸發事件的事件處理程式 |
| readyState | 獲取Ajax物件狀態碼: 0 = 未初始化(uninitialized) ,1 = 正在加載(loading),2 = 加載完畢(loaded), 3 = 互動(interactive), 4 = 完成(complete) |
| responseText | 從服務器行程回傳的資料的字串形式 |
| responseXML | 從服務器行程回傳的DOM兼容的檔案資料物件 |
| status | 從服務器回傳的數字代碼,如404(未找到)或200(就緒) |
| statusText | 伴隨狀態碼的字串資訊 |
Get、Post請求方式的底層實作
Get請求:
//1、獲得XMLHttpRequest物件,即ajax物件
var oRequest = getHttpRequest();
//獲取用戶在文本框輸入的值并進行拼接
var userName = user_name.value;
var userAge = user_age.value;
var getStr = "user_name="+ userName +"&user_age="+ userAge ;
//2、呼叫open方法,傳遞地址及請求方式
//中間的引數為具體的地址 (該地址需要帶get方式的請求引數)
oRequest.open('get' , 'http://localhost:3000/get?'+getStr , true);
//3、設定請求-回應狀態發生改變時的回呼函式 (回呼處理)
oRequest.onreadystatechange = function(){
if (oRequest.readyState == 4&&oRequest.status==200){
//請求-回應成功完成
var result = oRequest.responseText;
//將獲取到的回應資訊寫入到頁面中相應的id為message標簽里
var msgdiv = document.getElementById("message");
msgdiv.innerHTML = result;
}
};
//4、向服務器發送異步呼叫請求
oRequest.send();
//可以用onload事件來代替onreadystatechange事件 即將上面3、4步的代碼進行交換
/*
//3、發送請求
oRequest.send();
//4、獲取服務器端回應的資料
oRequest.onload = function () {
//請求-回應成功完成
var result = oRequest.responseText;
//將獲取到的回應資訊寫入到頁面中相應的id為message標簽里
var msgdiv = document.getElementById("message");
msgdiv.innerHTML = result;
}*/
Post請求:
//1、 獲得XMLHttpRequest物件,即ajax物件
var oRequest = getHttpRequest();
//獲取用戶在文本框輸入的值并進行拼接
var userName = user_name.value;
var userAge = user_age.value;
var postStr = "user_name="+ userName +"&user_age="+ userAge ;
//2、呼叫open方法,傳遞地址及請求方式
//中間的引數為請求地址 (該地址不需要帶請求引數)
oRequest.open('POST' , 'http://localhost:3000/post' , true);
//3、設定請求引數格式的型別(post引數必須要設定)
oRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
//4、設定請求-回應狀態發生改變時的回呼函式 (回呼處理)
oRequest.onreadystatechange = function(){
if (oRequest.readyState == 4&&oRequest.status==200){
var result = oRequest.responseText;
//將獲取到的回應資訊寫入到頁面中相應的id為message標簽里
var msgdiv = document.getElementById("message");
msgdiv.innerHTML = result;
}
};
//5、向服務器發送異步呼叫請求
oRequest.send(postStr);
// 同理,用onload事件實作
/*
//4、發送請求
oRequest.send(postStr);
//5、獲取服務器端回應的資料
oRequest.onload = function () {
//請求-回應成功完成
var result = oRequest.responseText;
//將獲取到的回應資訊寫入到頁面中相應的id為message標簽里
var msgdiv = document.getElementById("message");
msgdiv.innerHTML = result;
}*/
獲取服務器端的回應:
-
onreadystatechange 事件: 當 Ajax 狀態碼發生變化時將自動觸發該事件
- 在事件處理函式中可以獲取 Ajax 狀態碼并對其進行判斷,當狀態碼為 4 時就可以通過 responseText屬性 獲取服務器端的回應資料了
-
onload事件: 通過監聽onload事件,當Ajax物件接收完回應資料后觸發該事件,從而獲取服務器端的資料回應 (更推薦使用onload事件)
二者的區別:

服務器端回應的資料格式:
-
在真實的專案中,服務器端大多數情況下會以 JSON 物件作為回應資料的格式,當客戶端拿到回應資料時,要將 JSON 資料和 HTML 字串進行拼接,然后將拼接的結果展示在頁面中,
-
在 http 請求與回應的程序中,無論是請求引數還是回應內容,如果是物件型別,最終都會被轉換為物件字串進行傳輸,
-
JSON.parse()方法: 將 json 字串轉換為 json物件
客戶端請求引數的格式(Content-Type):
- application/x-www-form-urlencoded ,瀏覽器默認的編碼格式,即 ?key=value&key=value格式 ,例如:name=zhangsan&age=20&sex=男
- application/json ,json格式 例如: {name: ‘zhangsan’, age: ‘20’, sex: ‘男’}
JSON.stringify()方法: 將 json物件轉換為 json字串
注意: get 請求 是不能提交 json 物件資料格式的,傳統網站的表單 提交也是不支持 json 物件資料格式的,
Ajax錯誤處理:
- 1、網路暢通,服務器端能接收到請求,服務器端回傳的結果不是預期結果:
- 解決:可以判斷服務器端回傳的狀態碼,分別進行處理,xhr.status 獲取http狀態碼
- 2、網路暢通,服務器端沒有接收到請求,回傳404狀態碼:
- 解決:檢查請求地址是否錯誤,
- 3、網路暢通,服務器端能接收到請求,服務器端回傳500狀態碼:
- 解決:服務器端錯誤,找后端程式員進行溝通,
- 4、網路中斷,請求無法發送到服務器端:
- 解決:會觸發xhr物件下面的onerror事件,在onerror事件處理函式中對錯誤進行處理,
Ajax 函式的封裝
請求引數要考慮的問題:
-
1、請求引數位置的問題:將請求引數傳遞到ajax函式內部, 在函式內部根據請求方式的不同將請求引數放置在不同的位置
- get 放在 請求地址的后面
- post 放在 send方法中
-
2、請求引數格式的問題:
-
application/x-www-form-urlencoded:
- 引數名稱=引數值&引數名稱=引數值:name=zhangsan&age=20
-
application/json:
- Json物件格式: {name: ‘zhangsan’, age: 20}
-
傳遞物件資料型別對于函式的呼叫者更加友好
-
在函式內部物件資料型別轉換為字串資料型別更加方便
-
Ajax函式封裝的代碼:
- 使用時可直接呼叫ajax(options)方法,options引數可以是物件的格式
function ajax(options) {
// 存盤的是默認值
var defaults = {
type: 'get',
url: '',
data: {},
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: function () { },
error: function () { }
};
// 使用options物件中的屬性覆寫defaults物件中的屬性
Object.assign(defaults, options);
// 創建ajax物件
var xhr = new XMLHttpRequest();
// 拼接請求引數的變數
var params = '';
// 回圈用戶傳遞進來的物件格式引數
for (var attr in defaults.data) {
// 將引數轉換為字串格式
params += attr + '=' + defaults.data[attr] + '&';
}
// 將引數最后面的&截取掉
// 將截取的結果重新賦值給params變數
params = params.substr(0, params.length - 1);
// 判斷請求方式
if (defaults.type == 'get') {
defaults.url = defaults.url + '?' + params;
}
// 配置ajax物件
xhr.open(defaults.type, defaults.url);
// 如果請求方式為post 需要判斷引數型別
if (defaults.type == 'post') {
// 用戶希望的向服務器端傳遞的請求引數的型別
var contentType = defaults.header['Content-Type']
// 設定請求引數格式的型別
xhr.setRequestHeader('Content-Type', contentType);
// 判斷用戶希望的請求引數格式的型別
// 如果型別為json
if (contentType == 'application/json') {
// 向服務器端傳遞json資料格式的引數
xhr.send(JSON.stringify(defaults.data))
} else {
// 向服務器端傳遞普通型別的請求引數
xhr.send(params);
}
} else { // get的引數型別只能為普通型別
// 發送請求
xhr.send();
}
// 監聽xhr物件下面的onload事件
// 當xhr物件接收完回應資料后觸發
xhr.onload = function () {
// 獲取回應頭中的資料
var contentType = xhr.getResponseHeader('Content-Type');
// 服務器端回傳的資料
var responseText = xhr.responseText;
// 如果回應型別中包含applicaition/json
if (contentType.includes('application/json')) {
// 將json字串轉換為json物件
responseText = JSON.parse(responseText)
}
// 當http狀態碼等于200的時候
if (xhr.status == 200) {
// 請求成功 呼叫處理成功情況的函式
defaults.success(responseText, xhr);
} else {
// 請求失敗 呼叫處理失敗情況的函式
defaults.error(responseText, xhr);
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/295199.html
標籤:其他
下一篇:淺學JavaScript08
