如何使用element-ui二次封装ajax

Ajax应用最主要的特点是通过脚本操纵HTTP和Web服务器来传输数据,不会发生页面重载。可以仅向服务器发送并取回必须的数据,并在客户端通过JavaScript回应处理服务端的内容。
优点:因浏览器和服务器之间交换数据减少了,回应速度更快,同时Web服务器的负荷也减小了。

js封装ajax请求

  • data参数需要和请求头Content-Type对应
  • application/x-www-form-urlencoded:'name=哈哈&age=12——查询字符串,用&分割
  • application/json :{name:‘哈哈’,age:12} —— json字符串
  • multipart/form-data:new FormData() ——FormData对象,当为FormData类型,不要手动设置Content-Type
import {Loading} from 'element-ui';
import {messageInfo} from '~/untils/message'
import * as types from '../store/mutation-Types';
import store from '../store/store';
//装饰者模式:给对象动态的添加某一些职责
Function.prototype.before = function(beforeFn) {
	let _self = this;
	return function() {
		beforeFn.apply(this.arguments);
		_self.apply(this.arguments);
	}
}
Function.prototype.after = function(afterFn) {
	let _self = this;
	return function() {
		_self.apply(this, arguments);
		afterFn.apply(this, arguments);
	}
}
/*
 *@param settings 请求参数模仿jQuery ajax
 * 调用该方法,data参数需要和请求头Content-Type对应
 */
const http = {
	queue: {}, //请求队列,用来收集ajax请求
	loading: function() {
		var loading = Loading.service({
			text: '正在努力加载中...',
			background:'rgba(0,0,0,0.6)'
		});
		return loading;
	},
	//数据处理之字符串地址拼接
	getURLString: (url, data) => {
		if (!data) return '';
		let urlStr = data instanceof Object ? http.getQueryData(data) : data;
		if (url.indexOf('?') !== -1) {
			return urlStr;
		} else {
			return '?' + urlStr;
		}
	},
	//数据处理之数据类型判断
	getQueryData: (data) => {
		if(!data) return;
		if(typeof data === 'string' || data instanceof FormData){
			return data
		};
		return http.getQueryString(data);
	},
	//数据处理之对象转成字符串
	getQueryString: (data) => {
		let arrString = [];
		if (data instanceof Object) {
			Object.keys(data).forEach(item => {
				let val = data[item];
				arrString.push(encodeURIComponent(item) + '=' + encodeURIComponent(val));
			})
		}
		return arrString.join('&');
	},
	//将json对象转成json字符
	getJsonStr:(data)=>{
		return JSON.stringify(data);
	},
	ajax: (settings = {}) => {
		let _obj = Object.assign({
			url: '', //请求地址
			type: '', //请求类型 get post delete ...
			dataType: 'json', //返回的数据类型为json格式
			async: true, //是否异步,默认异步true
			data: null, //请求所需的参数
			headers: {}, //请求头
			timeout: 5000, //多少时间设为超时
			beforeSend: (xhr) => {}, //请求之前做什么
			success: (result, status, xhr) => {}, //成功之后做什么
			complete: (xhr, status) => {}, //请求完成之后做什么
			error: (xhr, status, error) => {}, //请求错误做什么
		}, settings)
		if (!_obj.url || !_obj.type || !_obj.dataType || !_obj.async) {
			messageInfo.messageInfo({
				type: 'error',
				content: '参数错误',
				duration: 0
			})
			return;
		}
		//创建xhr对象 兼容各个浏览器
		let xhr;
		if (typeof XMLHttpRequest !== 'undefined') {
			xhr = new XMLHttpRequest();
		} else if (window.ActiveXObject) {
			let aVersions = ["Msxml2.XMLHttp.5.0", "Msxml2.XMLHttp.4.0", "Msxml2.XMLHttp.3.0", "Msxml2.XMLHttp",
				"Microsoft.XMLHttp"
			];
			for (var i = 0, items = aVersions.length; i < items; i++) {
				try {
					xhr = new ActiveXObject(aVersions[i]);
					break;
				} catch (e) {

				}
			}
		}
		//是否携带跨域信息
		xhr.withCredentials = true;
		//监听请求之前
		xhr.addEventListener('loadstart', (e) => {
			_obj.beforeSend(xhr);

		});
		//监听请求时
		xhr.addEventListener('load', (e) => {
			const status = xhr.status;
			if (status >= 200 && status < 300 || status === 304) {
				let result;
				switch (xhr.responseType) {
					case 'text':
						result = xhr.responseText;
					case 'document':
						result = xhr.responseXML;
					default:
						result = xhr.response;
				}
				_obj.success(result, status, xhr);
			} else {
				_obj.error(xhr, status, e);
			}
		});
		//监听请求完成时
		xhr.addEventListener('loadend', (e) => {
			_obj.complete(xhr, xhr.status);
		});
		//监听请求错误
		xhr.addEventListener('error', (e) => {
			_obj.error(xhr, xhr.status, e);
		})
		//监听请求超时
		xhr.addEventListener('timeout', (e) => {
			_obj.error(xhr, 408, e);
		});
		//send函数是发送null,还是数据的标识判断
		let useURLString = false;
		let sType = _obj.type.toUpperCase();
		if (sType === 'GET' || sType === 'DELETE') {
			useURLString = true;
			_obj.url += http.getURLString(_obj.url, _obj.data);
		}
		//打开请求,在发送请求头时务必要打开请求。
		xhr.open(_obj.type, _obj.url, _obj.async);
		//设置响应的数据格式
		xhr.responseType = _obj.dataType;
		//设置请求头
		for (const key of Object.keys(_obj.headers)) {
			if(_obj.headers[key]){
				xhr.setRequestHeader(key, _obj.headers[key]);
			}
		}
		//设置超时时间
		if (_obj.async && _obj.timeout) {
			xhr.timeout = _obj.timeout;
		}
		//发送数据,当为get delete请求时发送null 否则数据处理
		xhr.send(useURLString?null:Object.values(_obj.headers).join('').indexOf('application/json')!==-1?http.getJsonStr(_obj.data):http.getQueryData(_obj.data));
	},
	request: (settings = {}) => {
		//错误处理函数
		let errorHandler = (xhr, status) => {
			if (status === 401) {
				messageInfo.messageInfo({
					type: 'error',
					content: '没有权限',
					duration: 0
				})
			} else if (status === 408) {
				messageInfo.messageInfo({
					type: 'error',
					content: '连接超时',
					duration: 0
				})
			}
		};
		//在执行错误函数之前 拦截错误信息执行函数
		settings.error = (settings.error || function() {}.before((xhr, status, e) => {
			delete http.queue[settings.url];
			if (Object.keys(http.queue).length === 0) {
				http.loading().close();
			}
			errorHandler(xhr, status);
		}));
		//在发送请求之前 开启loading...图标
		settings.beforeSend = (settings.beforeSend || function() {}.before(() => {
			if (Object.keys(http.queue).length === 0) {
				http.loading();
			}
			http.queue[settings.url] = settings.url;
		}));
		//在数据请求完毕 关闭loading...图标
		settings.complete = (settings.complete || function() {}.after(() => {
			delete http.queue[settings.url];
			if (Object.keys(http.queue).length === 0) {
				http.loading().close();
			}
		}));
		//请求成功的同一处理
		let successFn = settings.success;
		settings.success = (result, status, xhr) => {
			//兼容ie
			var res;
			if (typeof result === 'string') {
				res = JSON.parse(result)
			} else {
				res = result;
			}
			//登入接口设置
			if (res.type === 'signin') {
				successFn && successFn(res, status, xhr);
				return;
			}
			//统一处理接口code不等于200的问题
			if (!(res.code == 0 || res.code == 200)) {
				messageInfo.messageInfo({
					type: 'error',
					content: result.message && result.message!=null?result.message:result.data&&result.data!=null?result.data:'接口请求发生错误!',
					duration: 0
				})
			} else {
				successFn && successFn(res, status, xhr);
			}

		};
		// (http.ajax.before(addAuthorizationHeader)(settings));
		http.ajax(settings);
	},
	// 自定义请求头、添加权限请求头
	addAuthorizationHeader: (settings) => {
		settings.headers = settings.headers || {};
		const headerKey = 'Authorization'; // todo 权限头名称
		// 判断是否已经存在权限header
		let hasAuthorization = Object.keys(settings.headers).some(key => {
			return key === headerKey;
		});
		if (!hasAuthorization) {
			settings.headers[headerKey] = 'test'; // todo 从缓存中获取headerKey的值
		}
	},
	get: (url, option = {}, dataType = 'json') => {
		return new Promise((resolve, reject) => {
			http.request({
				url: url,
				type: 'GET',
				dataType: dataType,
				data: option.data,
				success: (res, status, xhr) => {
					resolve(res,status, xhr);
				},
				complete: option.complete,
				error: (xhr, status, e) => {
					reject(xhr, status, e);
				},
				headers: {
					// 'Content-Type': option.contentType //data数据格式要&字符串
				},
			})
		})
	},
	delete: (url, option = {}, dataType = 'json') => {
		return new Promise((resolve, reject) => {
			http.request({
				url: url,
				type: 'DELETE',
				dataType: dataType,
				data: option.data,
				success: (res, status, xhr) => {
					resolve(res, status, xhr);
				},
				complete: option.complete,
				error: (xhr, status, e) => {
					reject(xhr, status, e);
				},
			})
		})
	},
	// 调用此方法,参数data应为查询字符串或普通对象
	post: (url, option = {}, dataType = 'json') => {
		return new Promise((resolve, reject) => {
			http.request({
				url: url,
				type: 'POST',
				dataType: dataType,
				data: option.data,
				headers: {
					// 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' //data数据格式要&字符串
					'Content-Type':false,
				},
				success: (res, status, xhr) => {
					resolve(res, status, xhr);
				},
				complete: option.complete,
				error: (xhr, status, e) => {
					reject(xhr, status, e);
				},
			});
		})
	},
	// 调用此方法,参数data应为json字符串
	postBody: (url, option = {}, dataType = 'json') => {
		return new Promise((resolve, reject) => {
			http.request({
				url: url,
				type: 'POST',
				dataType: dataType,
				data: option.data,
				headers: {
					'Content-Type': 'application/json' //data数据格式json格式
				},
				success: (res, status, xhr) => {
					resolve(res, status, xhr);
				},
				complete: option.complete,
				error: (xhr, status, e) => {
					reject(xhr, status, e);
				},
			});
		})
	}
}
export default http;

以上的代码就完成了,在vue项目中的main.js文件引入代码即可使用。

你可能感兴趣的:(js,ajax,vue.js)