You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							169 lines
						
					
					
						
							5.6 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							169 lines
						
					
					
						
							5.6 KiB
						
					
					
				
								import deepMerge from "../function/deepMerge";
							 | 
						|
								import validate from "../function/test";
							 | 
						|
								class Request {
							 | 
						|
									// 设置全局默认配置
							 | 
						|
									setConfig(customConfig) {
							 | 
						|
										// 深度合并对象,否则会造成对象深层属性丢失
							 | 
						|
										this.config = deepMerge(this.config, customConfig);
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									// 主要请求部分
							 | 
						|
									request(options = {}) {
							 | 
						|
										// 检查请求拦截
							 | 
						|
										if (this.interceptor.request && typeof this.interceptor.request === 'function') {
							 | 
						|
											let tmpConfig = {};
							 | 
						|
											let interceptorRequest = this.interceptor.request(options);
							 | 
						|
											if (interceptorRequest === false) {
							 | 
						|
												// 返回一个处于pending状态中的Promise,来取消原promise,避免进入then()回调
							 | 
						|
												return new Promise(()=>{});
							 | 
						|
											}
							 | 
						|
											this.options = interceptorRequest;
							 | 
						|
										}
							 | 
						|
										options.dataType = options.dataType || this.config.dataType;
							 | 
						|
										options.responseType = options.responseType || this.config.responseType;
							 | 
						|
										options.url = options.url || '';
							 | 
						|
										options.params = options.params || {};
							 | 
						|
										options.header = Object.assign({}, this.config.header, options.header);
							 | 
						|
										options.method = options.method || this.config.method;
							 | 
						|
								
							 | 
						|
										return new Promise((resolve, reject) => {
							 | 
						|
											options.complete = (response) => {
							 | 
						|
												// 请求返回后,隐藏loading(如果请求返回快的话,可能会没有loading)
							 | 
						|
												uni.hideLoading();
							 | 
						|
												// 清除定时器,如果请求回来了,就无需loading
							 | 
						|
												clearTimeout(this.config.timer);
							 | 
						|
												this.config.timer = null;
							 | 
						|
												// 判断用户对拦截返回数据的要求,如果originalData为true,返回所有的数据(response)到拦截器,否则只返回response.data
							 | 
						|
												if(this.config.originalData) {
							 | 
						|
													// 判断是否存在拦截器
							 | 
						|
													if (this.interceptor.response && typeof this.interceptor.response === 'function') {
							 | 
						|
														let resInterceptors = this.interceptor.response(response);
							 | 
						|
														// 如果拦截器不返回false,就将拦截器返回的内容给this.$u.post的then回调
							 | 
						|
														if (resInterceptors !== false) {
							 | 
						|
															resolve(resInterceptors);
							 | 
						|
														} else {
							 | 
						|
															// 如果拦截器返回false,意味着拦截器定义者认为返回有问题,直接接入catch回调
							 | 
						|
															reject(response);
							 | 
						|
														}
							 | 
						|
													} else {
							 | 
						|
														// 如果要求返回原始数据,就算没有拦截器,也返回最原始的数据
							 | 
						|
														resolve(response);
							 | 
						|
													}
							 | 
						|
												} else {
							 | 
						|
													if (response.statusCode == 200) {
							 | 
						|
														if (this.interceptor.response && typeof this.interceptor.response === 'function') {
							 | 
						|
															let resInterceptors = this.interceptor.response(response.data);
							 | 
						|
															if (resInterceptors !== false) {
							 | 
						|
																resolve(resInterceptors);
							 | 
						|
															} else {
							 | 
						|
																reject(response.data);
							 | 
						|
															}
							 | 
						|
														} else {
							 | 
						|
															// 如果不是返回原始数据(originalData=false),且没有拦截器的情况下,返回纯数据给then回调
							 | 
						|
															resolve(response.data);
							 | 
						|
														}
							 | 
						|
													} else {
							 | 
						|
														// 不返回原始数据的情况下,服务器状态码不为200,modal弹框提示
							 | 
						|
														// if(response.errMsg) {
							 | 
						|
														// 	uni.showModal({
							 | 
						|
														// 		title: response.errMsg
							 | 
						|
														// 	});
							 | 
						|
														// }
							 | 
						|
														reject(response)
							 | 
						|
													}
							 | 
						|
												}
							 | 
						|
											}
							 | 
						|
								
							 | 
						|
											// 判断用户传递的URL是否/开头,如果不是,加上/,这里使用了uView的test.js验证库的url()方法
							 | 
						|
											options.url = validate.url(options.url) ? options.url : (this.config.baseUrl + (options.url.indexOf('/') == 0 ?
							 | 
						|
												options.url : '/' + options.url));
							 | 
						|
											
							 | 
						|
											// 是否显示loading
							 | 
						|
											// 加一个是否已有timer定时器的判断,否则有两个同时请求的时候,后者会清除前者的定时器id
							 | 
						|
											// 而没有清除前者的定时器,导致前者超时,一直显示loading
							 | 
						|
											if(this.config.showLoading && !this.config.timer) {
							 | 
						|
												this.config.timer = setTimeout(() => {
							 | 
						|
													uni.showLoading({
							 | 
						|
														title: this.config.loadingText,
							 | 
						|
														mask: this.config.loadingMask
							 | 
						|
													})
							 | 
						|
													this.config.timer = null;
							 | 
						|
												}, this.config.loadingTime);
							 | 
						|
											}
							 | 
						|
											uni.request(options);
							 | 
						|
										})
							 | 
						|
										// .catch(res => {
							 | 
						|
										// 	// 如果返回reject(),不让其进入this.$u.post().then().catch()后面的catct()
							 | 
						|
										// 	// 因为很多人都会忘了写后面的catch(),导致报错捕获不到catch
							 | 
						|
										// 	return new Promise(()=>{});
							 | 
						|
										// })
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									constructor() {
							 | 
						|
										this.config = {
							 | 
						|
											baseUrl: '', // 请求的根域名
							 | 
						|
											// 默认的请求头
							 | 
						|
											header: {},
							 | 
						|
											method: 'POST',
							 | 
						|
											// 设置为json,返回后uni.request会对数据进行一次JSON.parse
							 | 
						|
											dataType: 'json',
							 | 
						|
											// 此参数无需处理,因为5+和支付宝小程序不支持,默认为text即可
							 | 
						|
											responseType: 'text',
							 | 
						|
											showLoading: true, // 是否显示请求中的loading
							 | 
						|
											loadingText: '请求中...',
							 | 
						|
											loadingTime: 800, // 在此时间内,请求还没回来的话,就显示加载中动画,单位ms
							 | 
						|
											timer: null, // 定时器
							 | 
						|
											originalData: false, // 是否在拦截器中返回服务端的原始数据,见文档说明
							 | 
						|
											loadingMask: true, // 展示loading的时候,是否给一个透明的蒙层,防止触摸穿透
							 | 
						|
										}
							 | 
						|
									
							 | 
						|
										// 拦截器
							 | 
						|
										this.interceptor = {
							 | 
						|
											// 请求前的拦截
							 | 
						|
											request: null,
							 | 
						|
											// 请求后的拦截
							 | 
						|
											response: null
							 | 
						|
										}
							 | 
						|
								
							 | 
						|
										// get请求
							 | 
						|
										this.get = (url, data = {}, header = {}) => {
							 | 
						|
											return this.request({
							 | 
						|
												method: 'GET',
							 | 
						|
												url,
							 | 
						|
												header,
							 | 
						|
												data
							 | 
						|
											})
							 | 
						|
										}
							 | 
						|
								
							 | 
						|
										// post请求
							 | 
						|
										this.post = (url, data = {}, header = {}) => {
							 | 
						|
											return this.request({
							 | 
						|
												url,
							 | 
						|
												method: 'POST',
							 | 
						|
												header,
							 | 
						|
												data
							 | 
						|
											})
							 | 
						|
										}
							 | 
						|
										
							 | 
						|
										// put请求,不支持支付宝小程序(HX2.6.15)
							 | 
						|
										this.put = (url, data = {}, header = {}) => {
							 | 
						|
											return this.request({
							 | 
						|
												url,
							 | 
						|
												method: 'PUT',
							 | 
						|
												header,
							 | 
						|
												data
							 | 
						|
											})
							 | 
						|
										}
							 | 
						|
										
							 | 
						|
										// delete请求,不支持支付宝和头条小程序(HX2.6.15)
							 | 
						|
										this.delete = (url, data = {}, header = {}) => {
							 | 
						|
											return this.request({
							 | 
						|
												url,
							 | 
						|
												method: 'DELETE',
							 | 
						|
												header,
							 | 
						|
												data
							 | 
						|
											})
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
								}
							 | 
						|
								export default new Request
							 |