zhangmeng
2024-04-19 e3ba120cb766a17e098e58d11c39ffc600a3070c
commit | author | age
e3ba12 1 /**
Z 2  * @Class Request
3  * @description luch-request http请求插件
4  * @version 3.0.7
5  * @Author lu-ch
6  * @Date 2021-09-04
7  * @Email webwork.s@qq.com
8  * 文档: https://www.quanzhan.co/luch-request/
9  * github: https://github.com/lei-mu/luch-request
10  * DCloud: http://ext.dcloud.net.cn/plugin?id=392
11  * HBuilderX: beat-3.0.4 alpha-3.0.4
12  */
13
14 import dispatchRequest from './dispatchRequest'
15 import InterceptorManager from './InterceptorManager'
16 import mergeConfig from './mergeConfig'
17 import defaults from './defaults'
18 import { isPlainObject } from '../utils'
19 import clone from '../utils/clone'
20
21 export default class Request {
22     /**
23    * @param {Object} arg - 全局配置
24    * @param {String} arg.baseURL - 全局根路径
25    * @param {Object} arg.header - 全局header
26    * @param {String} arg.method = [GET|POST|PUT|DELETE|CONNECT|HEAD|OPTIONS|TRACE] - 全局默认请求方式
27    * @param {String} arg.dataType = [json] - 全局默认的dataType
28    * @param {String} arg.responseType = [text|arraybuffer] - 全局默认的responseType。支付宝小程序不支持
29    * @param {Object} arg.custom - 全局默认的自定义参数
30    * @param {Number} arg.timeout - 全局默认的超时时间,单位 ms。默认60000。H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序
31    * @param {Boolean} arg.sslVerify - 全局默认的是否验证 ssl 证书。默认true.仅App安卓端支持(HBuilderX 2.3.3+)
32    * @param {Boolean} arg.withCredentials - 全局默认的跨域请求时是否携带凭证(cookies)。默认false。仅H5支持(HBuilderX 2.6.15+)
33    * @param {Boolean} arg.firstIpv4 - 全DNS解析时优先使用ipv4。默认false。仅 App-Android 支持 (HBuilderX 2.8.0+)
34    * @param {Function(statusCode):Boolean} arg.validateStatus - 全局默认的自定义验证器。默认statusCode >= 200 && statusCode < 300
35    */
36     constructor(arg = {}) {
37         if (!isPlainObject(arg)) {
38             arg = {}
39             console.warn('设置全局参数必须接收一个Object')
40         }
41         this.config = clone({ ...defaults, ...arg })
42         this.interceptors = {
43             request: new InterceptorManager(),
44             response: new InterceptorManager()
45         }
46     }
47
48     /**
49    * @Function
50    * @param {Request~setConfigCallback} f - 设置全局默认配置
51    */
52     setConfig(f) {
53         this.config = f(this.config)
54     }
55
56     middleware(config) {
57         config = mergeConfig(this.config, config)
58         const chain = [dispatchRequest, undefined]
59         let promise = Promise.resolve(config)
60
61         this.interceptors.request.forEach((interceptor) => {
62             chain.unshift(interceptor.fulfilled, interceptor.rejected)
63         })
64
65         this.interceptors.response.forEach((interceptor) => {
66             chain.push(interceptor.fulfilled, interceptor.rejected)
67         })
68
69         while (chain.length) {
70             promise = promise.then(chain.shift(), chain.shift())
71         }
72
73         return promise
74     }
75
76     /**
77    * @Function
78    * @param {Object} config - 请求配置项
79    * @prop {String} options.url - 请求路径
80    * @prop {Object} options.data - 请求参数
81    * @prop {Object} [options.responseType = config.responseType] [text|arraybuffer] - 响应的数据类型
82    * @prop {Object} [options.dataType = config.dataType] - 如果设为 json,会尝试对返回的数据做一次 JSON.parse
83    * @prop {Object} [options.header = config.header] - 请求header
84    * @prop {Object} [options.method = config.method] - 请求方法
85    * @returns {Promise<unknown>}
86    */
87     request(config = {}) {
88         return this.middleware(config)
89     }
90
91     get(url, options = {}) {
92         return this.middleware({
93             url,
94             method: 'GET',
95             ...options
96         })
97     }
98
99     post(url, data, options = {}) {
100         return this.middleware({
101             url,
102             data,
103             method: 'POST',
104             ...options
105         })
106     }
107
108     // #ifndef MP-ALIPAY
109     put(url, data, options = {}) {
110         return this.middleware({
111             url,
112             data,
113             method: 'PUT',
114             ...options
115         })
116     }
117
118     // #endif
119
120     // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
121     delete(url, data, options = {}) {
122         return this.middleware({
123             url,
124             data,
125             method: 'DELETE',
126             ...options
127         })
128     }
129
130     // #endif
131
132     // #ifdef H5 || MP-WEIXIN
133     connect(url, data, options = {}) {
134         return this.middleware({
135             url,
136             data,
137             method: 'CONNECT',
138             ...options
139         })
140     }
141
142     // #endif
143
144     // #ifdef  H5 || MP-WEIXIN || MP-BAIDU
145     head(url, data, options = {}) {
146         return this.middleware({
147             url,
148             data,
149             method: 'HEAD',
150             ...options
151         })
152     }
153
154     // #endif
155
156     // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
157     options(url, data, options = {}) {
158         return this.middleware({
159             url,
160             data,
161             method: 'OPTIONS',
162             ...options
163         })
164     }
165
166     // #endif
167
168     // #ifdef H5 || MP-WEIXIN
169     trace(url, data, options = {}) {
170         return this.middleware({
171             url,
172             data,
173             method: 'TRACE',
174             ...options
175         })
176     }
177
178     // #endif
179
180     upload(url, config = {}) {
181         config.url = url
182         config.method = 'UPLOAD'
183         return this.middleware(config)
184     }
185
186     download(url, config = {}) {
187         config.url = url
188         config.method = 'DOWNLOAD'
189         return this.middleware(config)
190     }
191 }
192
193 /**
194  * setConfig回调
195  * @return {Object} - 返回操作后的config
196  * @callback Request~setConfigCallback
197  * @param {Object} config - 全局默认config
198  */