終極版封裝解決了以下幾個(gè)問(wèn)題。
服務(wù)器返回?cái)?shù)據(jù)格式的處理瀏覽器請(qǐng)求參數(shù)格式的處理狀態(tài)碼不是200調(diào)用失敗函數(shù)設(shè)置默認(rèn)參數(shù)減少冗余
這是終極版的代碼,代碼后面會(huì)有針對(duì)性的解釋。
分析終極版代碼:設(shè)置默認(rèn)參數(shù)減少冗余在ajax函數(shù)中設(shè)置defaults參數(shù)對(duì)象。為什么在調(diào)用ajax函數(shù)的時(shí)候傳入了參數(shù)還要再在函數(shù)里添加默認(rèn)參數(shù)呢,說(shuō)到底也是為了避免代碼冗余,如果創(chuàng)建多個(gè)ajax對(duì)象的話就會(huì)傳入可能會(huì)相同的參數(shù),我們只在調(diào)用的時(shí)候傳入特定的參數(shù)options,讓options覆蓋默認(rèn)參數(shù)defaults。在函數(shù)內(nèi)部使用defaults就可以完美的解決這個(gè)問(wèn)題。Object.assign(defaults, options)方就是讓defaults覆蓋options。
var defaults = { type: 'get',
url: '',
data: {},
header: { 'Content-Type': 'application/x-www-form-urlencoded'
},
success: function () {},
error: function () {}
};
// 使用options對(duì)象中的屬性覆蓋defaults對(duì)象中的屬性
Object.assign(defaults, options);復(fù)制代碼
Object.assign方法
補(bǔ)充:Object.assign方法
這里舉個(gè)代碼,夠應(yīng)付這篇文章,具體深入的還是看官方文檔
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target);
// expected output: Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget);
// expected output: Object { a: 1, b: 4, c: 5 }復(fù)制代碼
創(chuàng)建ajax對(duì)象,拼接請(qǐng)求參數(shù)
// 創(chuàng)建ajax對(duì)象
var xhr = new XMLHttpRequest();
// 拼接請(qǐng)求參數(shù)的變量
var params = '';
// 循環(huán)用戶傳遞進(jìn)來(lái)的對(duì)象格式參數(shù) for (var attr in defaults.data) {
// 將參數(shù)轉(zhuǎn)換為字符串格式
params = attr '=' defaults.data[attr] '&';
}
// 將參數(shù)最后面的&截取掉
// 將截取的結(jié)果重新賦值給params變量
params = params.substr(0, params.length - 1);復(fù)制代碼
瀏覽器請(qǐng)求參數(shù)格式的處理判斷請(qǐng)求方式是get合適post。如果是get就將請(qǐng)求參數(shù)拼接到請(qǐng)求地址后面,再配置ajax對(duì)象,用send方法發(fā)送請(qǐng)求;如果是post就先配置ajax對(duì)象,然后判斷請(qǐng)求參數(shù)的數(shù)據(jù)類型,如果是json類型就把數(shù)據(jù)類型轉(zhuǎn)換成字符串處理,如果是application/x-www-form-urlencoded就直用send方法向服務(wù)器傳遞普通請(qǐng)求參數(shù)發(fā)送請(qǐng)求。
if (defaults.type == 'get') {
defaults.url = defaults.url '?' params;
}
// 配置ajax對(duì)象
xhr.open(defaults.type, defaults.url);
// 如果請(qǐng)求方式為post if (defaults.type == 'post') {
// 用戶希望的向服務(wù)器端傳遞的請(qǐng)求參數(shù)的類型
var contentType = defaults.header['Content-Type']
// 設(shè)置請(qǐng)求參數(shù)格式的類型
xhr.setRequestHeader('Content-Type', contentType);
// 判斷用戶希望的請(qǐng)求參數(shù)格式的類型
// 如果類型為json if (contentType == 'application/json') {
// 向服務(wù)器端傳遞json數(shù)據(jù)格式的參數(shù)
xhr.send(JSON.stringify(defaults.data))
}else {
// 向服務(wù)器端傳遞普通類型的請(qǐng)求參數(shù)
xhr.send(params);
}
}else {
// 發(fā)送請(qǐng)求
xhr.send();
}復(fù)制代碼
服務(wù)器返回?cái)?shù)據(jù)格式的處理
4.當(dāng)請(qǐng)求發(fā)送成功,就會(huì)觸發(fā)onload事件,執(zhí)行函數(shù)。我們要對(duì)服務(wù)器響應(yīng)的數(shù)據(jù)進(jìn)行格式判斷,用getResponseHeader方法獲取響應(yīng)頭的數(shù)據(jù),Content-Type是響應(yīng)頭的屬性名稱。如果響應(yīng)頭中包含application/json這個(gè)字符,就說(shuō)明響應(yīng)的是json對(duì)象,但是傳輸?shù)臅r(shí)候是字符串形式傳輸,所以用json下的parse方法轉(zhuǎn)字符串為對(duì)象。
如果http的狀態(tài)碼是200就說(shuō)明客戶端發(fā)來(lái)的請(qǐng)求在服務(wù)器端得到了正確的處理。調(diào)用success函數(shù),否則調(diào)用錯(cuò)伏處理函數(shù)。
xhr.onload = function () {
// xhr.getResponseHeader()
// 獲取響應(yīng)頭中的數(shù)據(jù)
var contentType = xhr.getResponseHeader('Content-Type');
// 服務(wù)器端返回的數(shù)據(jù)
var responseText = xhr.responseText;
// 如果響應(yīng)類型中包含applicaition/json if (contentType.includes('application/json')) {
// 將json字符串轉(zhuǎn)換為json對(duì)象
responseText = JSON.parse(responseText)
}
// 當(dāng)http狀態(tài)碼等于200的時(shí)候 if (xhr.status == 200) {
// 請(qǐng)求成功 調(diào)用處理成功情況的函數(shù)
defaults.success(responseText, xhr);
}else {
// 請(qǐng)求失敗 調(diào)用處理失敗情況的函數(shù)
defaults.error(responseText, xhr);
}
}
}復(fù)制代碼
完整的封裝代碼貼出來(lái),如下所示:
<script type="text/javascript"> function ajax (options) {
// 存儲(chǔ)的是默認(rèn)值
var defaults = { type: 'get',
url: '',
data: {},
header: { 'Content-Type': 'application/x-www-form-urlencoded'
},
success: function () {},
error: function () {}
};
// 使用options對(duì)象中的屬性覆蓋defaults對(duì)象中的屬性
Object.assign(defaults, options);
// 創(chuàng)建ajax對(duì)象
var xhr = new XMLHttpRequest();
// 拼接請(qǐng)求參數(shù)的變量
var params = '';
// 循環(huán)用戶傳遞進(jìn)來(lái)的對(duì)象格式參數(shù) for (var attr in defaults.data) {
// 將參數(shù)轉(zhuǎn)換為字符串格式
params = attr '=' defaults.data[attr] '&';
}
// 將參數(shù)最后面的&截取掉
// 將截取的結(jié)果重新賦值給params變量
params = params.substr(0, params.length - 1);
// 判斷請(qǐng)求方式 if (defaults.type == 'get') {
defaults.url = defaults.url '?' params;
}
// 配置ajax對(duì)象
xhr.open(defaults.type, defaults.url);
// 如果請(qǐng)求方式為post if (defaults.type == 'post') {
// 用戶希望的向服務(wù)器端傳遞的請(qǐng)求參數(shù)的類型
var contentType = defaults.header['Content-Type']
// 設(shè)置請(qǐng)求參數(shù)格式的類型
xhr.setRequestHeader('Content-Type', contentType);
// 判斷用戶希望的請(qǐng)求參數(shù)格式的類型
// 如果類型為json if (contentType == 'application/json') {
// 向服務(wù)器端傳遞json數(shù)據(jù)格式的參數(shù)
xhr.send(JSON.stringify(defaults.data))
}else {
// 向服務(wù)器端傳遞普通類型的請(qǐng)求參數(shù)
xhr.send(params);
}
}else {
// 發(fā)送請(qǐng)求
xhr.send();
}
// 監(jiān)聽xhr對(duì)象下面的onload事件
// 當(dāng)xhr對(duì)象接收完響應(yīng)數(shù)據(jù)后觸發(fā)
xhr.onload = function () {
// xhr.getResponseHeader()
// 獲取響應(yīng)頭中的數(shù)據(jù)
var contentType = xhr.getResponseHeader('Content-Type');
// 服務(wù)器端返回的數(shù)據(jù)
var responseText = xhr.responseText;
// 如果響應(yīng)類型中包含applicaition/json if (contentType.includes('application/json')) {
// 將json字符串轉(zhuǎn)換為json對(duì)象
responseText = JSON.parse(responseText)
}
// 當(dāng)http狀態(tài)碼等于200的時(shí)候 if (xhr.status == 200) {
// 請(qǐng)求成功 調(diào)用處理成功情況的函數(shù)
defaults.success(responseText, xhr);
}else {
// 請(qǐng)求失敗 調(diào)用處理失敗情況的函數(shù)
defaults.error(responseText, xhr);
}
}
}
ajax({ type: 'post',
// 請(qǐng)求地址
url: 'http://localhost:3000/responseData',
success: function (data) {
console.log('這里是success函數(shù)');
console.log(data)
}
})
</script>復(fù)制代碼
文章結(jié)束
ok,到此封裝ajax函數(shù)完畢,為什么要封裝,減少使用多個(gè)ajax請(qǐng)求的時(shí)候代碼冗余。把代碼用函數(shù)封裝起來(lái)使用的時(shí)候調(diào)用函數(shù)就可。封裝ajax函數(shù)要考慮到以下幾點(diǎn):
請(qǐng)求方式(get),請(qǐng)求參數(shù)要與地址拼接后放到open方法中。請(qǐng)求方式post,請(qǐng)求參數(shù)類型是json數(shù)據(jù)類型,要將json轉(zhuǎn)字符串后放到send方法中。對(duì)服務(wù)器響應(yīng)處理時(shí)獲取響應(yīng)頭中的響應(yīng)數(shù)據(jù)格式。響應(yīng)的格式是json對(duì)象,處理響應(yīng)結(jié)果要將字符串轉(zhuǎn)json對(duì)象。設(shè)置ajax函數(shù)的默認(rèn)參數(shù)減少代碼冗余。
其他相關(guān)學(xué)習(xí)推薦:javascript
更多關(guān)于云服務(wù)器,域名注冊(cè),虛擬主機(jī)的問(wèn)題,請(qǐng)?jiān)L問(wèn)西部數(shù)碼官網(wǎng):m.ps-sw.cn