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.
350 lines
12 KiB
350 lines
12 KiB
/**
|
|
* A Request useing App network request design {@link http://www.wanlshop.com}
|
|
* @author 深圳前海万联科技有限公司 <wanlshop@i36k.com> < 本程序仅用作FastAdmin付费插件(多用户分销商城)测试使用,未经版权所有权人书面许可,不能自行用于商业用途!>
|
|
* @2019年9月10日12:52:20
|
|
* @version 1.0.1
|
|
*
|
|
**/
|
|
'use strict';
|
|
class Request {
|
|
|
|
/**
|
|
* @description 网络请求的默认配置
|
|
* @property {Object} config - 默认参数配置
|
|
* @property {string} config.baseUrl - 接口基地址
|
|
* @property {string} config.business - 接口响应的业务数据对象字段名,默认为data
|
|
*/
|
|
config = {
|
|
/*返回默认为res.data*/
|
|
baseUrl: '',
|
|
//method: 'GET',
|
|
//contentType: 'json',
|
|
business: 'data',
|
|
//dataType: 'json',
|
|
//encoding: 'UTF-8',
|
|
// skipInterceptorResponse: false,
|
|
// slashAbsoluteUrl: true,
|
|
// debug: false,
|
|
// loadingTip: undefined,
|
|
// loadingDuration: 500,
|
|
// responseType: 'text'
|
|
}
|
|
|
|
static posUrl(url) { /* 判断url是否为绝对路径 */
|
|
return /(http|https):\/\/([\w.]+\/?)\S*/.test(url)
|
|
}
|
|
|
|
static getUrl(config) {
|
|
let url = config.url || ''
|
|
let abs = Request.posUrl(url);
|
|
if (!abs) {
|
|
let f = config.slashAbsoluteUrl
|
|
if (f) {
|
|
abs = /^\/([\w.]+\/?)\S*/.test(url)
|
|
}
|
|
}
|
|
return abs ? url : (config.baseUrl + url)
|
|
}
|
|
|
|
static getContentType(config) {
|
|
var type = config.contentType || 'json'
|
|
var charset = config.encoding || 'UTF-8'
|
|
if (type === 'json') {
|
|
return 'application/json;charset=' + charset
|
|
} else if (type === 'form') {
|
|
return 'application/x-www-form-urlencoded;charset=' + charset
|
|
} else if (type === 'file') {
|
|
return 'multipart/form-data;charset=' + charset
|
|
} else if (type === 'text') {
|
|
return 'text/plain;charset=' + charset
|
|
} else if (type === 'html') {
|
|
return 'text/html;charset=' + charset
|
|
} else {
|
|
throw new Error('unsupported content type : ' + type)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @property {Object} interceptor 拦截器
|
|
*
|
|
*/
|
|
interceptor = {
|
|
/**
|
|
* @description define the interceptor before request
|
|
* @param {function}
|
|
*/
|
|
request: undefined,
|
|
response: undefined,
|
|
fail: undefined
|
|
}
|
|
|
|
/**
|
|
* @description set default request options
|
|
* @param {Object} config - the default options
|
|
* @param {string} config.baseUrl baseUrl - the base url
|
|
* @param {boolean} config.debug debug - enable debug to log
|
|
*/
|
|
setConfig(config) {
|
|
this.config = Object.assign(this.config, config)
|
|
}
|
|
|
|
request(options = {}) {
|
|
var that = this;
|
|
if (options.data === undefined) {
|
|
options.data = {}
|
|
}
|
|
if (options.header === undefined) {
|
|
options.header = {}
|
|
}
|
|
|
|
let _options = Object.assign({}, this.config, options)
|
|
_options = Object.assign(options, _options)
|
|
|
|
_options.url = Request.getUrl(_options)
|
|
if (!_options.header['Content-Type']) {
|
|
_options.header['Content-Type'] = Request.getContentType(_options)
|
|
}
|
|
let _config = _options
|
|
if (that.interceptor.request && typeof that.interceptor.request === 'function') {
|
|
_config = that.interceptor.request(_options)
|
|
}
|
|
let task = undefined
|
|
let promise = new Promise((resolve, reject) => {
|
|
|
|
let extras = {
|
|
|
|
}
|
|
that._prepare(that, _config, extras)
|
|
// let cancel = (_config) => {
|
|
// that._fail(that, _config, {
|
|
// errMsg: 'request:canceled',
|
|
// statusCode: -1
|
|
// }, resolve, reject)
|
|
// next = false
|
|
// }
|
|
|
|
if (_config.contentType === 'file') {
|
|
task = uni.uploadFile({
|
|
..._config,
|
|
success: res => {
|
|
that._success(that, _config, res, resolve, reject)
|
|
},
|
|
fail: res => {
|
|
that._fail(that, _config, res, resolve, reject)
|
|
},
|
|
complete: (res) => {
|
|
that._complete(that, _config, res, extras)
|
|
}
|
|
})
|
|
if (_config.progress && typeof _config.progress === 'function') {
|
|
task.onProgressUpdate(_res => {
|
|
_config.progress(_res, task)
|
|
})
|
|
}
|
|
} else {
|
|
task = uni.request({
|
|
..._config,
|
|
timeout: 6000,
|
|
success: res => {
|
|
that._success(that, _config, res, resolve, reject)
|
|
},
|
|
fail: res => {
|
|
that._fail(that, _config, res, resolve, reject)
|
|
},
|
|
complete: (res) => {
|
|
that._complete(that, _config, res, extras)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
if (_config.success || _config.fail || _config.complete) {
|
|
return task;
|
|
}
|
|
return promise;
|
|
}
|
|
|
|
/**
|
|
* @method
|
|
* @description execute a get request
|
|
* @param {Object} options - 参数选项
|
|
* @param {string} options.url - 请求地址
|
|
* @param {string} [options.method=GET] - 请求方法 GET|POST
|
|
* @param {string} [options.contentType=json] - 请求类型,为json(默认),form
|
|
* @param {Object} [options.data] - 请求参数
|
|
* @param {string} [options.encoding] - 请求编码,默认为utf-8
|
|
* @param {string} [options.dataType] - 如果设为 json(默认),会尝试对返回的数据做一次 JSON.parse
|
|
* @param {string} [options.business] - 接口响应的业务数据对象字段名,默认为data,如果返回整个业务对象,则需要设置为undefined
|
|
* @param {string} [options.skipInterceptorResponse] - 是否跳过响应过滤器,如需跳过,请置true
|
|
* @param {string} [options.slashAbsoluteUrl] - 是否视以/开头的url为绝对地址,默认为false,此设置仅当初步判断url为非绝对地址时有效
|
|
* @param {string} [options.loadingTip] - 是否在请求前显示文字为参数值的loading提示,如果是,会在请求结束后自动关闭loading提示
|
|
* @param {string} [options.loadingDuration] - 设置loadingTip时的最小loading显示时间
|
|
*
|
|
* @return {Promise} promise
|
|
* @example
|
|
* $request.get({
|
|
url: 'foo/bar',
|
|
data: {
|
|
param1: value1
|
|
}
|
|
})
|
|
* @see {@link https://uniapp.dcloud.io/api/request/request}
|
|
*/
|
|
get(options = {}) {
|
|
options.method = 'GET'
|
|
return this.request(options)
|
|
}
|
|
|
|
/**
|
|
* @method
|
|
* @description execute a post request
|
|
* @param {Object} options - 参数选项
|
|
* @param {string} options.url - 请求地址
|
|
* @param {string} [options.method=POST] - 请求方法 GET|POST
|
|
* @param {string} [options.contentType=json] - 请求类型,为json(默认),form
|
|
* @param {Object} [options.data] - 请求参数
|
|
* @param {string} [options.encoding] - 请求编码,默认为utf-8
|
|
* @param {string} [options.dataType] - 如果设为 json(默认),会尝试对返回的数据做一次 JSON.parse
|
|
* @param {string} [options.business] - 接口响应的业务数据对象字段名,默认为data,如果返回整个业务对象,则需要设置为undefined
|
|
* @param {string} [options.skipInterceptorResponse] - 是否跳过响应过滤器,如需跳过,请置true
|
|
* @param {string} [options.slashAbsoluteUrl] - 是否视以/开头的url为绝对地址,默认为false,此设置仅当初步判断url为非绝对地址时有效
|
|
* @param {string} [options.loadingTip] - 是否在请求前显示文字为参数值的loading提示,如果是,会在请求结束后自动关闭loading提示
|
|
* @param {string} [options.loadingDuration] - 设置loadingTip时的最小loading显示时间
|
|
*
|
|
* @return {Promise} promise
|
|
* @example
|
|
* $request.post({
|
|
url: 'foo/bar',
|
|
data: {
|
|
param1: value1
|
|
}
|
|
})
|
|
* @see {@link https://uniapp.dcloud.io/api/request/request}
|
|
*/
|
|
post(options = {}) {
|
|
options.method = 'POST'
|
|
return this.request(options)
|
|
}
|
|
/**
|
|
* @method
|
|
* @description execute a get request
|
|
* @param {Object} options - 参数选项
|
|
* @param {string} options.url - 请求地址
|
|
* @param {string} [options.method=GET] - 请求方法 GET|POST
|
|
* @param {string} [options.contentType=json] - 请求类型,为json(默认),form
|
|
* @param {Object} [options.data] - 请求参数
|
|
* @param {string} [options.encoding] - 请求编码,默认为utf-8
|
|
* @param {string} [options.dataType] - 如果设为 json(默认),会尝试对返回的数据做一次 JSON.parse
|
|
* @param {string} [options.business] - 接口响应的业务数据对象字段名,默认为data,如果返回整个业务对象,则需要设置为undefined
|
|
* @param {string} [options.skipInterceptorResponse] - 是否跳过响应过滤器,如需跳过,请置true
|
|
* @param {string} [options.slashAbsoluteUrl] - 是否视以/开头的url为绝对地址,默认为false,此设置仅当初步判断url为非绝对地址时有效
|
|
* @param {string} [options.loadingTip] - 是否在请求前显示文字为参数值的loading提示,如果是,会在请求结束后自动关闭loading提示
|
|
* @param {string} [options.loadingDuration] - 设置loadingTip时的最小loading显示时间
|
|
*
|
|
* @return {Promise} promise
|
|
* @example
|
|
* $request.upload({
|
|
url: 'foo/bar',
|
|
filePath: res.tempFilePaths[0];
|
|
data: {
|
|
param1: value1
|
|
}
|
|
})
|
|
* @see {@link https://uniapp.dcloud.io/api/request/network-file}
|
|
*/
|
|
upload(options = {}) {
|
|
options.method = 'POST'
|
|
options.contentType = 'file'
|
|
return this.request(options)
|
|
}
|
|
|
|
_success = function(that, _config, res, resolve, reject) {
|
|
if (res.statusCode >= 200 && res.statusCode <= 401) { // http ok
|
|
var result = res.data // 全局的拦截器
|
|
var parseFileJson = _config.contentType === 'file' && typeof result === 'string' && (_config.dataType ===
|
|
undefined || _config.dataType === 'json')
|
|
if (parseFileJson) {
|
|
result = JSON.parse(res.data);
|
|
}
|
|
var skip = _config.skipInterceptorResponse
|
|
if (that.interceptor.response && typeof that.interceptor.response === 'function' && !skip) {
|
|
// TODO 对于某些特殊接口,比如访问其它系统,全局拦截器可能不适合
|
|
// 这种情况下,要根据_config在全局拦截器中将其它系统的返回适配为本系统的业务对象
|
|
result = that.interceptor.response(result, _config)
|
|
}
|
|
if (skip || result.success) { // 接口调用业务成功
|
|
var _data = _config.business ? result[_config.business] : result;
|
|
if (_config.debug) {
|
|
console.log('response success: ', _data)
|
|
}
|
|
_config.success ? _config.success(_data) : resolve(_data)
|
|
return;
|
|
}
|
|
}
|
|
that._fail(that, _config, res, resolve, reject)
|
|
}
|
|
|
|
_fail = function(that, _config, res, resolve, reject) {
|
|
if (_config.debug) {
|
|
console.error('response failure: ', res)
|
|
}
|
|
if (res.errMsg === 'request:fail abort') {
|
|
return
|
|
}
|
|
var result = res
|
|
if (that.interceptor.fail && typeof that.interceptor.fail === 'function') {
|
|
result = that.interceptor.fail(res, _config)
|
|
}
|
|
_config.fail ? _config.fail(result) : reject(result)
|
|
}
|
|
|
|
_prepare = function(that, _config, obj = {}) {
|
|
obj.startTime = Date.now()
|
|
if (_config.loadingTip) {
|
|
// 开启Loading -----------------------------------
|
|
uni.showLoading({
|
|
title: _config.loadingTip
|
|
})
|
|
}
|
|
if (_config.contentType === 'file') {
|
|
if (_config.formData === undefined || _config.formData === null) {
|
|
_config.formData = _config.data
|
|
delete _config.data
|
|
}
|
|
delete _config.header['Content-Type']
|
|
delete _config.header['Referer']
|
|
_config.method = 'POST'
|
|
}
|
|
if (_config.debug) {
|
|
console.log('request: ', _config)
|
|
}
|
|
}
|
|
|
|
_complete = function(that, _config, res, obj = {}) {
|
|
obj.endTime = Date.now()
|
|
if (_config.debug) {
|
|
console.log('请求用时 ' + (obj.endTime - obj.startTime) + ' 毫秒')
|
|
}
|
|
if (_config.loadingTip) {
|
|
let diff = obj.endTime - obj.startTime;
|
|
let duration = _config.loadingDuration || 500
|
|
if (diff < duration) {
|
|
diff = duration - diff
|
|
} else {
|
|
diff = 0
|
|
}
|
|
// 关闭Loading -----------------------------------
|
|
setTimeout(function() {
|
|
uni.hideLoading()
|
|
}, diff)
|
|
}
|
|
}
|
|
|
|
}
|
|
/**
|
|
*
|
|
*/
|
|
var request = new Request()
|
|
/**
|
|
* @module {Request} request
|
|
*/
|
|
export default request
|
|
|