For an elegant front end, every brick moved must be elegant and beautiful. Let’s start with request encapsulation. If you use uni, you can use wx. Instead of uni. Will do)
1. Define a deep-copy method for merging parameters in the help module file
// deep merge of JS objects
export function deepMerge( target = {}, source = {} ) {
target = deepClone( target );
if ( typeoftarget ! = ='object' || typeofsource ! = ='object' ) return false;
for ( const prop in source ) {
if ( !source.hasOwnProperty( prop ) ) continue;
if ( prop in target ) {
if ( typeoftarget[ prop ] ! = ='object' ) {
target[ prop ] = source[ prop ];
} else {
if ( typeofsource[ prop ] ! = ='object' ) {
target[ prop ] = source[ prop ];
} else {
if ( target[ prop ].concat && source[ prop ].concat ) {
target[ prop ] = target[ prop ].concat( source[ prop ] );
} else{ target[ prop ] = deepMerge( target[ prop ], source[ prop ] ); }}}}else{ target[ prop ] = source[ prop ]; }}return target;
}
Copy the code
2. Define a URL’s regular validation method and place it in the validate module file
/** * Verify the URL format */
export function urlRegExp( value ) {
return /http(s)? :\/\/([\w-]+\.) +[\w-]+(\/[\w-.\/?%&=]*)? /.test( value )
}
Copy the code
3. Request wrapped code
import {
deepMerge
} from './help.js'
import {
urlRegExp
} from './validate.js'
class Http {
constructor( ) {
this.config = {
// The requested root domain name
baseUrl: ' '.// The default request header
header: {},
method: 'POST'.// Set to JSON. Upon return, wx.request will parse the data json.parse
dataType: 'json'.// No action is required for this parameter
responseType: 'text'.// Whether loading is enabled by default
loading: true,}/ / the interceptor
this.interceptor = {
// Interception before request
request: null.// Interception after request
response: null
}
/ / get request
this.get = ( url, data = {}, loading = this.config.loading, header = {} ) = > {
return this.request( {
method: 'GET',
url,
header,
data
}, loading )
}
/ / post request
this.post = ( url, data = {}, loading = this.config.loading, header = {} ) = > {
return this.request( {
url,
method: 'POST',
header,
data
}, loading )
}
/ / put request
this.put = ( url, data = {}, loading = this.config.loading, header = {} ) = > {
return this.request( {
url,
method: 'PUT',
header,
data
}, loading )
}
/ / delete request
this.delete = ( url, data = {}, loading = this.config.loading, header = {} ) = > {
return this.request( {
url,
method: 'DELETE',
header,
data
}, loading )
}
}
// Set the global default configuration
create( customConfig ) {
// Merge objects in depth, otherwise deep attributes of the object will be lost
this.config = deepMerge( this.config, customConfig );
}
// The main request section
request( options = {}, loading = this.config.loading ) {
options.loading = loading
// Check request interception
if ( this.interceptor.request && typeof this.interceptor.request === 'function' ) {
let tmpConfig = {};
let interceptorRequest = this.interceptor.request( options );
if ( interceptorRequest === false ) {
// Return a Promise in a pending state to cancel the original Promise and avoid the then() callback
return new Promise( ( ) =>{}); }this.options = interceptorRequest;
}
options.dataType = options.dataType || this.config.dataType;
options.responseType = options.responseType || this.config.responseType;
options.url = options.url || ' ';
options.params = options.params || {};
options.header = Object.assign( this.config.header, options.header );
options.method = options.method || this.config.method;
return new Promise( ( resolve, reject ) = > {
options.complete = ( response ) = > {
response.loading = loading
// Determine whether an interceptor exists
if ( this.interceptor.response && typeof this.interceptor.response === 'function' ) {
let resInterceptors = this.interceptor.response( response );
// If the interceptor does not return false, plug in the then callback directly
if( resInterceptors ! = =false ) {
resolve( resInterceptors );
} else {
// If the interceptor returns false, it means that the interceptor definer thinks there is a problem with the return and calls the catch callback directlyreject( response.data || response ); }}else {
// If raw data is required, the original data is returned, even if there is no interceptorresolve( response ); }}// Determine if the URL passed by the user starts with /, if not, add /,
options.url = urlRegExp( options.url ) ? options.url : ( this.config.baseUrl + ( options.url
.indexOf( '/') = =0 ?
options.url : '/'+ options.url ) ); wx.request( options ); }}})export default Http
Copy the code
4. Use Demo: Here we create a new request.js file
Import the HTTP file you just wrapped and configure the request using the request response interceptor
const ACCESS_TOKEN = 'AurhToken' // Key of token certificate
import HTTP from './http.js'
// Create configuration information
const requestConfig = {
baseUrl: ' '.// https://test.request.api
timeout: 10 * 1000.// Request timeout
}
// Initialize the request instance
const newHttp = new HTTP( )
newHttp.create( requestConfig )
// Request interception configuration items
const LoadingDelayTime = 750 // showLoading Delay time
let requestNum = 0 // Number of requests
let showLoading = false / / loading condition
let loadingTimer = null // showLoading timer
let RedirectTimer = null // Log in to the timer again
// Request interceptor
newHttp.interceptor.request = config= > {
/ / add loading
if ( config.loading ) {
requestNum++
Loading is created for the first request in the queue
if (requestNum === 1) {
loadingTimer = setTimeout(() = > {
showLoading = true
uni.showLoading({
title: 'loading... '.mask: true
})
}, LoadingDelayTime)
}
}
// Add Token credentials
if ( typeofconfig.header ! = ='object' ) config.header = {}
config.header[ ACCESS_TOKEN ] = 'This is a token content'
// We can customize the parameters of the request
// config.data = buildOptions( config.data )
return config
}
// Response interceptor
newHttp.interceptor.response = response= > {
/ / close the Loading
if ( response.loading ) {
requestNum--
if ( requestNum === 0 ) {
if ( loadingTimer ) {
clearTimeout( loadingTimer )
loadingTimer = null
}
if ( showLoading ) {
showLoading = false
wx.hideLoading( )
}
}
}
// All errors are handled uniformly
if ( response.statusCode === 200 ) {
const {
code,
message
} = response.data
switch ( code ) {
case 0: // Successful response
return response.data
break;
case 401: // Login credentials expire and log in again
// Create a timer to prevent multiple requests from returning to 401
if ( RedirectTimer ) clearTimeout( RedirectTimer )
RedirectTimer = null
RedirectTimer = setTimeout( ( ) => {
wx.showToast( {
title: Please log in first.icon: 'none'.duration: 1500})let timerS = setTimeout( ( ) => {
clearTimeout( timerS )
// Log out
/ /...
}, 1500)},2000 )
return false
break;
default:
wx.showToast( {
title: message || 'Network error 1'.icon: 'none'})return false}}else {
wx.showToast( {
title: 'Network error 2'.icon: 'none'.duration: 2000})return false}}/ / GET request
export function requestGet( {
url,
data = {},
loading = true,
header = {}
} ) {
return newHttp.get( url, data, loading, header )
}
/ / POST request
export function requestPost( {
url,
data = {},
loading = true,
header = {}
} ) {
return newHttp.post( url, data, loading, header )
}
/ / PUT request
export function requestPut( {
url,
data = {},
loading = true,
header = {}
} ) {
return newHttp.put( url, data, loading, header )
}
/ / DELETE request
export function requestDelete( {
url,
data = {},
loading = true,
header = {}
} ) {
return newHttp.delete( url, data, loading, header )
}
Copy the code
tips
Finally is in the small program in each module of the use, in app.js we encapsulated the request method, finally throw ok.
App.js sample code attached:
import { requestGet,requestPost,requestPut,requestDelete } from './utils/request.js'
App({
$Http: {
get: requestGet,
post: requestPost,
put: requestPut,
delete: requestDelete
}
})
Copy the code
Request sample code:
// pages/home/home.js
const App = getApp()
page({
onLoad() {
this.getDetail()
},
getDetail() {
const params = {
/ / request API
url: '/api/detail/get'.// Request parameters
data: {
id: 123.type: 1
},
// Whether to enable loading. The default value is true
loading: true
}
App.$Http.post(params).then(res= > {
// The request succeeded
console.log(res)
})
}
})
Copy the code