封裝一個強大的AJAX庫

話很少說,直接上代碼javascript

/* * 支持的參數配置項 * url * method:'GET' * data:null * dataType:'json' * async:true * cache:true * success:null * error:null * headers:null * timeout:null */
~ function () {
function ajax(options) {
	return new init(options);
}

/* ==AJAX處理的核心== */
let regGET = /^(GET|DELETE|HEAD|OPTIONS)$/i;
let defaults = {
	url: '', //=>請求的API接口地址
	method: 'GET', //=>請求方式 GET/POST/DELETE/PUT/HEAD/OPTIONS
	data: null, //=>傳遞給服務器的信息:支持格式STRING和OBJECT,若是是OBJECT,咱們須要把其處理爲x-www-form-urlencoded格式;GET請求是把信息做爲問號參數傳遞給服務器,POST請求是放到請求主體中傳遞給服務器;
	dataType: 'JSON', //=>把服務器返回結果處理成爲對應的格式 JSON/TEXT/XML
	async: true, //=>是否異步請求
	cache: true, //=>只對GET請求有做用:設置爲FALSE,在URL的末尾加隨機數來清除緩存
	timeout: null, //=>超時時間
	headers: null, //=>設置請求頭信息(請求頭信息不能是中文,因此咱們須要爲其編碼)
	success: null, //=>從服務器獲取成功後執行 把獲取的結果、狀態信息、XHR傳遞給它
	error: null //=>獲取失敗後執行 把錯誤信息傳遞給它
};

function init(options = {}) {
	//=>參數初始化:把傳遞的配置項替換默認的配置項
	this.options = Object.assign(defaults, options);
	this.xhr = null;
	this.send();
}

ajax.prototype = {
	constructor: ajax,
	version: 1.0,
	//=>發送AJAX請求
	send() {
		let xhr = null,
			{
				url,
				method,
				async,
				data,
				cache,
				timeout,
				dataType,
				headers,
				success,
				error
			} = this.options;
		this.xhr = xhr = new XMLHttpRequest;

		//=>處理DATA:若是是GET請求把處理後的DATA放在URL末尾傳遞給服務器
		data = this.handleData();
		if (data !== null && regGET.test(method)) {
			url += `${this.checkASK(url)}${data}`;
			data = null;
		}

		//=>處理CACHE:若是是GET而且CACHE是FALSE須要清除緩存
		if (cache === false && regGET.test(method)) {
			url += `${this.checkASK(url)}_=${Math.random()}`;
		}

		xhr.open(method, url, async);

		//=>超時處理
		timeout !== null ? xhr.timeout = timeout : null;

		//=>設置請求頭信息
		if (Object.prototype.toString.call(headers) === "[object Object]") {
			for (let key in headers) {
				if (!headers.hasOwnProperty(key)) break;
				xhr.setRequestHeader(key, encodeURIComponent(headers[key]));
			}
		}

		xhr.onreadystatechange = () => {
			let {
				status,
				statusText,
				readyState: state,
				responseText,
				responseXML
			} = xhr;
			if (/^(2|3)\d{2}$/.test(status)) {
				//=>成功
				if (state === 4) {
					switch (dataType.toUpperCase()) {
						case 'JSON':
							responseText = JSON.parse(responseText);
							break;
						case 'XML':
							responseText = responseXML;
							break;
					}
					success && success(responseText, statusText, xhr);
				}
				return;
			}
			//=>失敗的
			typeof error === "function" ? error(statusText, xhr) : null;
		}
		xhr.send(data);
	},
	//=>關於DATA參數的處理
	handleData() {
		let {
			data
		} = this.options;
		if (data === null || typeof data === "string") return data;
		//=>只有DATA是一個對象,咱們須要把它變爲xxx=xxx&xxx=xxx這種格式字符串
		let str = ``;
		for (let key in data) {
			if (!data.hasOwnProperty(key)) break;
			str += `${key}=${data[key]}&`;
		}
		str = str.substring(0, str.length - 1);
		return str;
	},
	//=>檢測URL中是否存在問號
	checkASK(url) {
		return url.indexOf('?') === -1 ? '?' : '&';
	}
};
init.prototype = ajax.prototype;

window._ajax = ajax;
}();
複製代碼
相關文章
相關標籤/搜索