溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

ajax函數(shù)封裝的基本實(shí)現(xiàn)方法

發(fā)布時(shí)間:2020-09-21 09:17:15 來源:億速云 閱讀:197 作者:小新 欄目:web開發(fā)

這篇文章主要介紹ajax函數(shù)封裝的基本實(shí)現(xiàn)方法,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

前言

前面一篇文章講了ajax的原理,作用和實(shí)現(xiàn)。但是都只是實(shí)現(xiàn)一個(gè)ajax請(qǐng)求響應(yīng)操作,瀏覽器和服務(wù)器之間請(qǐng)求響應(yīng)不會(huì)只有一次,加入請(qǐng)求響應(yīng)100次,那么要寫100次近似的代碼嗎?

這篇文章就是解決如何發(fā)送多個(gè)ajax的問題。如果你對(duì)ajax沒有了解,我的上一篇文章《認(rèn)識(shí)ajax》用心看完,大約5分鐘就可以get到這篇文章內(nèi)容。

這篇文章其實(shí)就是講了一個(gè)函數(shù)。接下來一起來看看吧。

封裝的思想

發(fā)送多個(gè)請(qǐng)求的操作都是相同的,如果寫多個(gè)就會(huì)有重復(fù)的代碼。避免代碼冗余就可以借助函數(shù)的思想,將ajax操作的代碼封裝到一個(gè)函數(shù)中,不同的請(qǐng)求函數(shù)傳遞的參數(shù)所有不同。如果要多次發(fā)送ajax請(qǐng)求的時(shí)候,就調(diào)用我們封裝好的函數(shù)就好了。

ajax函數(shù)封裝的基本實(shí)現(xiàn)

前面說用函數(shù)封裝ajax,那么ajax實(shí)現(xiàn)的四步放到函數(shù)中,然后調(diào)用這個(gè)函數(shù),因?yàn)閭鬟f的參數(shù)比較多,所以參數(shù)用一個(gè)對(duì)象options來表示。這個(gè)對(duì)象里面包括請(qǐng)求方式,請(qǐng)求地址,請(qǐng)求發(fā)送成功后觸發(fā)的請(qǐng)求處理函數(shù)。

我么看看下面的例子。代碼中將ajax操作封裝到ajax函數(shù)中,調(diào)用ajax函數(shù),傳入?yún)?shù),xht下的onload事件觸發(fā)后,調(diào)用了sunccess函數(shù),將相應(yīng)內(nèi)容xhr.responsetext打印到控制臺(tái)中。

function ajax(options) {
    var xhr = new XMLHttpRequest();
    xhr.open(options.type, options.url);
    xhr.send();
    xhr.onload = function () {
        options.success(xhr.responsetext);
    }
}
ajax({ 
     type: 'get',
     url: 'http://www.example.com',
     success: function (data) { 
         console.log(data);
     }
 })復(fù)制代碼

請(qǐng)求參數(shù)的封裝

上面代碼實(shí)現(xiàn)了基本的封裝,接下來講一講如何對(duì)請(qǐng)求參數(shù)進(jìn)行封裝,上一篇文章中介紹了post方法和get方法這兩種方法發(fā)送請(qǐng)求,不同的請(qǐng)求方式請(qǐng)求參數(shù)也是放置在不同的位置的,比如get方法拼接在url后,post方法放在send方法里面。我們?cè)赼jax方法的實(shí)參對(duì)象中加一個(gè)data屬性,data屬性值就是請(qǐng)求參數(shù)。

在ajax這個(gè)函數(shù)中利用for-in循環(huán)拼接請(qǐng)求參數(shù),將請(qǐng)求參數(shù)多余的的&去掉。后然對(duì)請(qǐng)求類型做出判斷,如果是get請(qǐng)求就把剛剛拼接好的params拼接到url后面;如果是post請(qǐng)求將參數(shù)放到send方法中,并使用xhr對(duì)象下的setRequestHeader方法設(shè)置請(qǐng)求參數(shù)格式的類型。

代碼如下:

	var xhr = new XMLHttpRequest();
	// 拼接請(qǐng)求參數(shù)的變量
	var params = '';
	// 循環(huán)用戶傳遞進(jìn)來的對(duì)象格式參數(shù)	for (var attr in options.data) {
		// 將參數(shù)轉(zhuǎn)換為字符串格式
		params += attr + '=' + options.data[attr] + '&';
	}
	// 將參數(shù)最后面的&截取掉 
	// 將截取的結(jié)果重新賦值給params變量
	params = params.substr(0, params.length - 1);

	// 判斷請(qǐng)求方式	if (options.type == 'get') {
		options.url = options.url + '?' + params;
	}


	// 配置ajax對(duì)象
	xhr.open(options.type,options.url);
	// 如果請(qǐng)求方式為post	if (options.type == 'post') {
		// 設(shè)置請(qǐng)求參數(shù)格式的類型
		xhr.setRequestHeader('Content-Type', contentType);
    	// 向服務(wù)器端傳遞請(qǐng)求參數(shù)
		xhr.send(params);
		
	}else {
		// 發(fā)送請(qǐng)求
		xhr.send();
	}
        xhr.onload = function () {
        options.success(xhr.responsetext);
        }
        
  ajax({ 
     type: 'get',
     url: 'http://www.example.com',
     data: {
         name:'linglong',
         age:20
     },
     success: function (data) { 
         console.log(data);
     }
 })復(fù)制代碼

封裝終極版

進(jìn)過前面兩個(gè)熱身后直接看ajax封裝的最后版本。 終極版封裝解決了以下幾個(gè)問題。

  • 服務(wù)器返回?cái)?shù)據(jù)格式的處理
  • 瀏覽器請(qǐng)求參數(shù)格式的處理
  • 狀態(tài)碼不是200調(diào)用失敗函數(shù)
  • 設(shè)置默認(rèn)參數(shù)減少冗余

這是終極版的代碼,代碼后面會(huì)有針對(duì)性的解釋。

分析終極版代碼:

設(shè)置默認(rèn)參數(shù)減少冗余

  1. 在ajax函數(shù)中設(shè)置defaults參數(shù)對(duì)象。為什么在調(diào)用ajax函數(shù)的時(shí)候傳入了參數(shù)還要再在函數(shù)里添加默認(rèn)參數(shù)呢,說到底也是為了避免代碼冗余,如果創(chuàng)建多個(gè)ajax對(duì)象的話就會(huì)傳入可能會(huì)相同的參數(shù),我們只在調(diào)用的時(shí)候傳入特定的參數(shù)options,讓options覆蓋默認(rèn)參數(shù)defaults。在函數(shù)內(nèi)部使用defaults就可以完美的解決這個(gè)問題。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)來的對(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ù)格式的處理

  1. 判斷請(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è)字符,就說明響應(yīng)的是json對(duì)象,但是傳輸?shù)臅r(shí)候是字符串形式傳輸,所以用json下的parse方法轉(zhuǎn)字符串為對(duì)象。 如果http的狀態(tài)碼是200就說明客戶端發(fā)來的請(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ù)制代碼

完整的封裝代碼貼出來,如下所示:

<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)來的對(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ù)制代碼

封裝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ù)減少代碼冗余。

以上是ajax函數(shù)封裝的基本實(shí)現(xiàn)方法的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI