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

/**
* 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