hello,Ajax(Ajax的封裝)

前言

前面一篇文章講了ajax的原理,做用和實現。可是都只是實現一個ajax請求響應操做,瀏覽器和服務器之間請求響應不會只有一次,加入請求響應100次,那麼要寫100次近似的代碼嗎?javascript

這篇文章就是解決如何發送多個ajax的問題。若是你對ajax沒有了解,個人上一篇文章hello,ajax(0基礎入門篇)用心看完,大約5分鐘就能夠get到這篇文章內容。java

這篇文章其實就是講了一個函數。接下來一塊兒來看看吧。ajax

封裝的思想

發送多個請求的操做都是相同的,若是寫多個就會有重複的代碼。避免代碼冗餘就能夠藉助函數的思想,將ajax操做的代碼封裝到一個函數中,不一樣的請求函數傳遞的參數全部不一樣。若是要屢次發送ajax請求的時候,就調用咱們封裝好的函數就行了。json

ajax函數封裝的基本實現

前面說用函數封裝ajax,那麼ajax實現的四步放到函數中,而後調用這個函數,由於傳遞的參數比較多,因此參數用一個對象options來表示。這個對象裏面包括請求方式,請求地址,請求發送成功後觸發的請求處理函數。瀏覽器

我麼看看下面的例子。代碼中將ajax操做封裝到ajax函數中,調用ajax函數,傳入參數,xht下的onload事件觸發後,調用了sunccess函數,將相應內容xhr.responsetext打印到控制檯中。bash

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);
     }
 })
複製代碼

請求參數的封裝

上面代碼實現了基本的封裝,接下來說一講如何對請求參數進行封裝,上一篇文章中介紹了post方法和get方法這兩種方法發送請求,不一樣的請求方式請求參數也是放置在不一樣的位置的,好比get方法拼接在url後,post方法放在send方法裏面。咱們在ajax方法的實參對象中加一個data屬性,data屬性值就是請求參數。服務器

在ajax這個函數中利用for-in循環拼接請求參數,將請求參數多餘的的&去掉。後然對請求類型作出判斷,若是是get請求就把剛剛拼接好的params拼接到url後面;若是是post請求將參數放到send方法中,並使用xhr對象下的setRequestHeader方法設置請求參數格式的類型。app

代碼以下:函數

var xhr = new XMLHttpRequest();
	// 拼接請求參數的變量
	var params = '';
	// 循環用戶傳遞進來的對象格式參數
	for (var attr in options.data) {
		// 將參數轉換爲字符串格式
		params += attr + '=' + options.data[attr] + '&';
	}
	// 將參數最後面的&截取掉 
	// 將截取的結果從新賦值給params變量
	params = params.substr(0, params.length - 1);

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


	// 配置ajax對象
	xhr.open(options.type,options.url);
	// 若是請求方式爲post
	if (options.type == 'post') {
		// 設置請求參數格式的類型
		xhr.setRequestHeader('Content-Type', contentType);
    	// 向服務器端傳遞請求參數
		xhr.send(params);
		
	}else {
		// 發送請求
		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);
     }
 })
複製代碼

封裝終極版

進過前面兩個熱身後直接看ajax封裝的最後版本。 終極版封裝解決了如下幾個問題。post

  • 服務器返回數據格式的處理
  • 瀏覽器請求參數格式的處理
  • 狀態碼不是200調用失敗函數
  • 設置默認參數減小冗餘

這是終極版的代碼,代碼後面會有針對性的解釋。

分析終極版代碼:

設置默認參數減小冗餘

  1. 在ajax函數中設置defaults參數對象。爲何在調用ajax函數的時候傳入了參數還要再在函數裏添加默認參數呢,說到底也是爲了不代碼冗餘,若是建立多個ajax對象的話就會傳入可能會相同的參數,咱們只在調用的時候傳入特定的參數options,讓options覆蓋默認參數defaults。在函數內部使用defaults就能夠完美的解決這個問題。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對象中的屬性覆蓋defaults對象中的屬性
		Object.assign(defaults, options);
複製代碼

Object.assign方法

補充:Object.assign方法

這裏舉個代碼,夠應付這篇文章,具體深刻的仍是看官方文檔

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 }

複製代碼

建立ajax對象,拼接請求參數

// 建立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);
複製代碼

瀏覽器請求參數格式的處理

  1. 判斷請求方式是get合適post。若是是get就將請求參數拼接到請求地址後面,再配置ajax對象,用send方法發送請求;若是是post就先配置ajax對象,而後判斷請求參數的數據類型,若是是json類型就把數據類型轉換成字符串處理,若是是application/x-www-form-urlencoded就直用send方法向服務器傳遞普通請求參數發送請求。
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 {
			// 發送請求
			xhr.send();
		}
複製代碼

服務器返回數據格式的處理

4.當請求發送成功,就會觸發onload事件,執行函數。咱們要對服務器響應的數據進行格式判斷,用getResponseHeader方法獲取響應頭的數據,Content-Type是響應頭的屬性名稱。若是響應頭中包含application/json這個字符,就說明響應的是json對象,可是傳輸的時候是字符串形式傳輸,因此用json下的parse方法轉字符串爲對象。 若是http的狀態碼是200就說明客戶端發來的請求在服務器端獲得了正確的處理。調用success函數,不然調用錯伏處理函數。

xhr.onload = function () {
			// xhr.getResponseHeader()
			// 獲取響應頭中的數據
			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);
			}
		}
	}
複製代碼

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

<script type="text/javascript">
	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 {
			// 發送請求
			xhr.send();
		}
		// 監聽xhr對象下面的onload事件
		// 當xhr對象接收完響應數據後觸發
		xhr.onload = function () {
			// xhr.getResponseHeader()
			// 獲取響應頭中的數據
			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);
			}
		}
	}
	ajax({
		type: 'post',
		// 請求地址
		url: 'http://localhost:3000/responseData',
		success: function (data) {
			console.log('這裏是success函數');
			console.log(data)
		}
	})
</script>
複製代碼

文章結束

ok,到此封裝ajax函數完畢,爲何要封裝,減小使用多個ajax請求的時候代碼冗餘。把代碼用函數封裝起來使用的時候調用函數就可。封裝ajax函數要考慮到如下幾點:

  • 請求方式(get),請求參數要與地址拼接後放到open方法中。
  • 請求方式post,請求參數類型是json數據類型,要將json轉字符串後放到send方法中。
  • 對服務器響應處理時獲取響應頭中的響應數據格式。
  • 響應的格式是json對象,處理響應結果要將字符串轉json對象。
  • 設置ajax函數的默認參數減小代碼冗餘。

最近特別喜歡蠟筆小新,蠢萌蠢萌。

推薦你們去看嘿嘿嘿。

下篇文章見,筆芯.....

相關文章
相關標籤/搜索