blob: ced1744780138553dd8896ac154465477a0b4662 [file] [log] [blame]
guangchao.xu070005a2020-12-07 09:56:40 +08001import deepMerge from "../function/deepMerge";
2import validate from "../function/test";
3class Request {
4 // 设置全局默认配置
5 setConfig(customConfig) {
6 // 深度合并对象,否则会造成对象深层属性丢失
7 this.config = deepMerge(this.config, customConfig);
8 }
9
10 // 主要请求部分
11 request(options = {}) {
12 // 检查请求拦截
13 if (this.interceptor.request && typeof this.interceptor.request === 'function') {
14 let tmpConfig = {};
15 let interceptorRequest = this.interceptor.request(options);
16 if (interceptorRequest === false) {
17 // 返回一个处于pending状态中的Promise,来取消原promise,避免进入then()回调
18 return new Promise(()=>{});
19 }
20 this.options = interceptorRequest;
21 }
22 options.dataType = options.dataType || this.config.dataType;
23 options.responseType = options.responseType || this.config.responseType;
24 options.url = options.url || '';
25 options.params = options.params || {};
26 options.header = Object.assign(this.config.header, options.header);
27 options.method = options.method || this.config.method;
28
29 return new Promise((resolve, reject) => {
30 options.complete = (response) => {
31 // 请求返回后,隐藏loading(如果请求返回快的话,可能会没有loading)
32 uni.hideLoading();
33 // 清除定时器,如果请求回来了,就无需loading
34 clearTimeout(this.config.timer);
35 this.config.timer = null;
36 // 判断用户对拦截返回数据的要求,如果originalData为true,返回所有的数据(response)到拦截器,否则只返回response.data
37 if(this.config.originalData) {
38 // 判断是否存在拦截器
39 if (this.interceptor.response && typeof this.interceptor.response === 'function') {
40 let resInterceptors = this.interceptor.response(response);
41 // 如果拦截器不返回false,就将拦截器返回的内容给this.$u.post的then回调
42 if (resInterceptors !== false) {
43 resolve(resInterceptors);
44 } else {
45 // 如果拦截器返回false,意味着拦截器定义者认为返回有问题,直接接入catch回调
46 reject(response);
47 }
48 } else {
49 // 如果要求返回原始数据,就算没有拦截器,也返回最原始的数据
50 resolve(response);
51 }
52 } else {
53 if (response.statusCode == 200) {
54 if (this.interceptor.response && typeof this.interceptor.response === 'function') {
55 let resInterceptors = this.interceptor.response(response.data);
56 if (resInterceptors !== false) {
57 resolve(resInterceptors);
58 } else {
59 reject(response.data);
60 }
61 } else {
62 // 如果不是返回原始数据(originalData=false),且没有拦截器的情况下,返回纯数据给then回调
63 resolve(response.data);
64 }
65 } else {
66 // 不返回原始数据的情况下,服务器状态码不为200,modal弹框提示
67 // if(response.errMsg) {
68 // uni.showModal({
69 // title: response.errMsg
70 // });
71 // }
72 reject(response)
73 }
74 }
75 }
76
77 // 判断用户传递的URL是否/开头,如果不是,加上/,这里使用了uView的test.js验证库的url()方法
78 options.url = validate.url(options.url) ? options.url : (this.config.baseUrl + (options.url.indexOf('/') == 0 ?
79 options.url : '/' + options.url));
80
81 // 是否显示loading
82 // 加一个是否已有timer定时器的判断,否则有两个同时请求的时候,后者会清除前者的定时器id
83 // 而没有清除前者的定时器,导致前者超时,一直显示loading
84 if(this.config.showLoading && !this.config.timer) {
85 this.config.timer = setTimeout(() => {
86 uni.showLoading({
87 title: this.config.loadingText,
88 mask: this.config.loadingMask
89 })
90 this.config.timer = null;
91 }, this.config.loadingTime);
92 }
93 uni.request(options);
94 })
95 // .catch(res => {
96 // // 如果返回reject(),不让其进入this.$u.post().then().catch()后面的catct()
97 // // 因为很多人都会忘了写后面的catch(),导致报错捕获不到catch
98 // return new Promise(()=>{});
99 // })
100 }
101
102 constructor() {
103 this.config = {
104 baseUrl: '', // 请求的根域名
105 // 默认的请求头
106 header: {},
107 method: 'POST',
108 // 设置为json,返回后uni.request会对数据进行一次JSON.parse
109 dataType: 'json',
110 // 此参数无需处理,因为5+和支付宝小程序不支持,默认为text即可
111 responseType: 'text',
112 showLoading: true, // 是否显示请求中的loading
113 loadingText: '请求中...',
114 loadingTime: 800, // 在此时间内,请求还没回来的话,就显示加载中动画,单位ms
115 timer: null, // 定时器
116 originalData: false, // 是否在拦截器中返回服务端的原始数据,见文档说明
117 loadingMask: true, // 展示loading的时候,是否给一个透明的蒙层,防止触摸穿透
118 }
119
120 // 拦截器
121 this.interceptor = {
122 // 请求前的拦截
123 request: null,
124 // 请求后的拦截
125 response: null
126 }
127
128 // get请求
129 this.get = (url, data = {}, header = {}) => {
130 return this.request({
131 method: 'GET',
132 url,
133 header,
134 data
135 })
136 }
137
138 // post请求
139 this.post = (url, data = {}, header = {}) => {
140 return this.request({
141 url,
142 method: 'POST',
143 header,
144 data
145 })
146 }
147
148 // put请求,不支持支付宝小程序(HX2.6.15)
149 this.put = (url, data = {}, header = {}) => {
150 return this.request({
151 url,
152 method: 'PUT',
153 header,
154 data
155 })
156 }
157
158 // delete请求,不支持支付宝和头条小程序(HX2.6.15)
159 this.delete = (url, data = {}, header = {}) => {
160 return this.request({
161 url,
162 method: 'DELETE',
163 header,
164 data
165 })
166 }
167 }
168}
169export default new Request