request.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. import {
  2. BASE_URL
  3. } from '@/env'
  4. export default class Request {
  5. config = {
  6. baseUrl: BASE_URL,
  7. header: {
  8. 'content-type': 'application/json',
  9. 'platform': uni.getStorageSync('platform'),
  10. },
  11. method: 'GET',
  12. dataType: 'json',
  13. // #ifndef MP-ALIPAY || APP-PLUS
  14. responseType: 'text',
  15. // #endif
  16. custom: {},
  17. // #ifdef MP-ALIPAY
  18. timeout: 30000,
  19. // #endif
  20. // #ifdef APP-PLUS
  21. sslVerify: false
  22. // #endif
  23. }
  24. static posUrl(url) { /* 判断url是否为绝对路径 */
  25. return /(http|https):\/\/([\w.]+\/?)\S*/.test(url)
  26. }
  27. static addQueryString(params) {
  28. let paramsData = ''
  29. Object.keys(params).forEach(function(key) {
  30. paramsData += key + '=' + encodeURIComponent(params[key]) + '&'
  31. })
  32. return paramsData.substring(0, paramsData.length - 1)
  33. }
  34. /**
  35. * @property {Function} request 请求拦截器
  36. * @property {Function} response 响应拦截器
  37. * @type {{request: Request.interceptor.request, response: Request.interceptor.response}}
  38. */
  39. interceptor = {
  40. /**
  41. * @param {Request~requestCallback} cb - 请求之前拦截,接收一个函数(config, cancel)=> {return config}。第一个参数为全局config,第二个参数为函数,调用则取消本次请求。
  42. */
  43. request: (cb) => {
  44. if (cb) {
  45. this.requestBeforeFun = cb
  46. }
  47. },
  48. /**
  49. * @param {Request~responseCallback} cb 响应拦截器,对响应数据做点什么
  50. * @param {Request~responseErrCallback} ecb 响应拦截器,对响应错误做点什么
  51. */
  52. response: (cb, ecb) => {
  53. if (cb && ecb) {
  54. this.requestComFun = cb
  55. this.requestComFail = ecb
  56. }
  57. }
  58. }
  59. requestBeforeFun(config) {
  60. return config
  61. }
  62. requestComFun(response) {
  63. return response
  64. }
  65. requestComFail(response) {
  66. return response
  67. }
  68. /**
  69. * 自定义验证器,如果返回true 则进入响应拦截器的响应成功函数(resolve),否则进入响应拦截器的响应错误函数(reject)
  70. * @param { Number } statusCode - 请求响应体statusCode(只读)
  71. * @return { Boolean } 如果为true,则 resolve, 否则 reject
  72. */
  73. validateStatus(statusCode) {
  74. return statusCode === 200
  75. }
  76. /**
  77. * @Function
  78. * @param {Request~setConfigCallback} f - 设置全局默认配置
  79. */
  80. setConfig(f) {
  81. this.config = f(this.config)
  82. }
  83. /**
  84. * @Function
  85. * @param {Object} options - 请求配置项
  86. * @prop {String} options.url - 请求路径
  87. * @prop {Object} options.data - 请求参数
  88. * @prop {Object} [options.responseType = config.responseType] [text|arraybuffer] - 响应的数据类型
  89. * @prop {Object} [options.dataType = config.dataType] - 如果设为 json,会尝试对返回的数据做一次 JSON.parse
  90. * @prop {Object} [options.header = config.header] - 请求header
  91. * @prop {Object} [options.method = config.method] - 请求方法
  92. * @returns {Promise<unknown>}
  93. */
  94. async request(options = {}) {
  95. options.baseUrl = this.config.baseUrl
  96. options.dataType = options.dataType || this.config.dataType
  97. // #ifndef MP-ALIPAY || APP-PLUS
  98. options.responseType = options.responseType || this.config.responseType
  99. // #endif
  100. // #ifdef MP-ALIPAY
  101. options.timeout = options.timeout || this.config.timeout
  102. // #endif
  103. options.url = options.url || ''
  104. options.data = options.data || {}
  105. options.params = options.params || {}
  106. options.header = options.header || this.config.header
  107. options.method = options.method || this.config.method
  108. options.custom = { ...this.config.custom,
  109. ...(options.custom || {})
  110. }
  111. // #ifdef APP-PLUS
  112. options.sslVerify = options.sslVerify === undefined ? this.config.sslVerify : options.sslVerify
  113. // #endif
  114. return new Promise((resolve, reject) => {
  115. let next = true
  116. let handleRe = {}
  117. options.complete = (response) => {
  118. response.config = handleRe
  119. if (this.validateStatus(response.statusCode)) { // 成功
  120. response = this.requestComFun(response)
  121. resolve(response.data)
  122. } else if (401 === response.statusCode) {
  123. response = this.requestComFun(response)
  124. resolve(response.data)
  125. } else if (500 === response.statusCode) {
  126. resolve(response.data)
  127. } else {
  128. response = this.requestComFail(response)
  129. reject(response)
  130. }
  131. }
  132. const cancel = (t = 'handle cancel', config = options) => {
  133. const err = {
  134. errMsg: t,
  135. config: config
  136. }
  137. reject(err)
  138. next = false
  139. }
  140. handleRe = { ...this.requestBeforeFun(options, cancel)
  141. }
  142. const _config = { ...handleRe
  143. }
  144. if (!next) return
  145. delete _config.custom
  146. let mergeUrl = Request.posUrl(_config.url) ? _config.url : (_config.baseUrl + _config.url)
  147. if (JSON.stringify(_config.params) !== '{}') {
  148. const paramsH = Request.addQueryString(_config.params);
  149. mergeUrl += mergeUrl.indexOf('?') === -1 ? `?${paramsH}` : `&${paramsH}`
  150. }
  151. _config.url = mergeUrl
  152. uni.request(_config)
  153. })
  154. }
  155. get(url, options = {}) {
  156. return this.request({
  157. url,
  158. method: 'GET',
  159. ...options
  160. })
  161. }
  162. post(url, data, options = {}) {
  163. return this.request({
  164. url,
  165. data,
  166. method: 'POST',
  167. ...options
  168. })
  169. }
  170. upload(url, {
  171. // #ifdef APP-PLUS
  172. files,
  173. // #endif
  174. // #ifdef MP-ALIPAY
  175. fileType,
  176. // #endif
  177. filePath,
  178. name,
  179. header,
  180. formData,
  181. custom
  182. }) {
  183. return new Promise((resolve, reject) => {
  184. let next = true
  185. let handleRe = {}
  186. const globalHeader = { ...this.config.header
  187. }
  188. delete globalHeader['content-type']
  189. const pubConfig = {
  190. baseUrl: this.config.baseUrl,
  191. url,
  192. // #ifdef APP-PLUS
  193. files,
  194. // #endif
  195. // #ifdef MP-ALIPAY
  196. fileType,
  197. // #endif
  198. filePath,
  199. method: 'UPLOAD',
  200. name,
  201. header: header || globalHeader,
  202. formData,
  203. custom: { ...this.config.custom,
  204. ...(custom || {})
  205. },
  206. complete: (response) => {
  207. response.config = handleRe
  208. if (response.statusCode === 200) { // 成功
  209. response = this.requestComFun(response)
  210. resolve(response)
  211. } else {
  212. response = this.requestComFail(response)
  213. reject(response)
  214. }
  215. }
  216. }
  217. const cancel = (t = 'handle cancel', config = pubConfig) => {
  218. const err = {
  219. errMsg: t,
  220. config: config
  221. }
  222. reject(err)
  223. next = false
  224. }
  225. handleRe = { ...this.requestBeforeFun(pubConfig, cancel)
  226. }
  227. const _config = { ...handleRe
  228. }
  229. if (!next) return
  230. delete _config.custom
  231. _config.url = Request.posUrl(_config.url) ? _config.url : (_config.baseUrl + _config.url)
  232. uni.uploadFile(_config)
  233. })
  234. }
  235. }
  236. /**
  237. * setConfig回调
  238. * @return {Object} - 返回操作后的config
  239. * @callback Request~setConfigCallback
  240. * @param {Object} config - 全局默认config
  241. */
  242. /**
  243. * 请求拦截器回调
  244. * @return {Object} - 返回操作后的config
  245. * @callback Request~requestCallback
  246. * @param {Object} config - 全局config
  247. * @param {Function} [cancel] - 取消请求钩子,调用会取消本次请求
  248. */
  249. /**
  250. * 响应拦截器回调
  251. * @return {Object} - 返回操作后的response
  252. * @callback Request~responseCallback
  253. * @param {Object} response - 请求结果 response
  254. */
  255. /**
  256. * 响应错误拦截器回调
  257. * @return {Object} - 返回操作后的response
  258. * @callback Request~responseErrCallback
  259. * @param {Object} response - 请求结果 response
  260. */