首先在项目 pages
平级创建 service
文件夹,然后分别建立3个文件分别是:
interceptors.ts
– 请求响应拦截器。
import Taro from '@tarojs/taro'
import { HTTP_STATUS } from './status'
import cartStroe from '../store/user'
const customInterceptor = (chain:any) => {
const requestParams = chain.requestParams
return chain.proceed(requestParams).then((res:any) => {
if(requestParams.loading) Taro.hideLoading()
switch(res.statusCode) {
case HTTP_STATUS.SUCCESS:
const result = res.data
if(res.data.code === 200) {
result.success = true
} else {
if(requestParams.openErrTips && result.msg) Taro.showToast({ title: result.msg, icon: 'none' })
if(result.code === 210 || result.code === 220) {
cartStroe.setStatus(false)
cartStroe.setUser({})
Taro.showToast({ title: (result.code === 210 ? '未登录,请先登陆' : '登录信息失效,请重新登陆' ), icon: 'none' })
Taro.navigateTo({ url: '/pages/login/index' })
return Promise.reject(result)
}
}
return result
case HTTP_STATUS.CREATED:
return Promise.reject('请求成功并且服务器创建了新的资源')
case HTTP_STATUS.ACCEPTED:
return Promise.reject('接受请求但没创建资源')
case HTTP_STATUS.CLIENT_ERROR:
return Promise.reject('服务器不理解请求的语法')
case HTTP_STATUS.AUTHENTICATE:
return Promise.reject('请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应')
case HTTP_STATUS.FORBIDDEN:
return Promise.reject('服务器拒绝请求')
case HTTP_STATUS.NOT_FOUND:
return Promise.reject('服务器找不到请求的网页')
case HTTP_STATUS.SERVER_ERROR:
return Promise.reject('(服务器内部错误) 服务器遇到错误,无法完成请求')
case HTTP_STATUS.BAD_GATEWAY:
return Promise.reject('(错误网关) 服务器作为网关或代理,从上游服务器收到无效响应')
case HTTP_STATUS.SERVICE_UNAVAILABLE:
return Promise.reject('(服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。')
case HTTP_STATUS.GATEWAY_TIMEOUT:
return Promise.reject('(网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求')
default:
console.log('请开发者检查请求拦截未匹配到错误,返回statusCode :>> ', res.statusCode)
break
}
})
}
const interceptors = [customInterceptor, Taro.interceptors.logInterceptor]
export default interceptors
status.ts
– HTTP 通用响应状态码提示(方便开发者寻找请求错误源)。
export const HTTP_STATUS = {
SUCCESS: 200,
CREATED: 201,
ACCEPTED: 202,
CLIENT_ERROR: 400,
AUTHENTICATE: 401,
FORBIDDEN: 403,
NOT_FOUND: 404,
SERVER_ERROR: 500,
BAD_GATEWAY: 502,
SERVICE_UNAVAILABLE: 503,
GATEWAY_TIMEOUT: 504
}
index.ts
– 封装请求导出供调用。
import Taro from '@tarojs/taro'
import interceptors from './interceptors'
interceptors.forEach(interceptorItem => Taro.addInterceptor(interceptorItem))
declare namespace RequestProps {
interface Method {
'GET',
'POST',
'PUT',
'DELETE'
}
interface Options {
url: string,
method: keyof Method,
data: any,
loading?: boolean,
loadingTitle?: string,
contentType?: string,
openErrTips?: boolean
}
interface requestParams {
url: string,
method: keyof Method,
data: any,
header: any,
loading?: boolean,
loadingTitle?: string,
contentType?: string,
openErrTips?: boolean
}
}
const getVersion = () => {
switch (__wxConfig.envVersion)
{
case 'develop':
return 'http://develop.gavinpeng.club'
case 'trial':
return 'http://trial.gavinpeng.club'
case 'release':
return 'http://release.gavinpeng.club'
default:
return 'http://develop.gavinpeng.club'
}
}
class Request {
baseOptions(options: RequestProps.Options) {
let { url, method, data } = options
let { loading, loadingTitle, contentType, openErrTips, ...rest } = data
if(loading) Taro.showLoading({ title: loadingTitle || '加载中...', mask: true })
const requestParams: RequestProps.requestParams = {
url: getVersion() + url,
method,
data: rest,
header: {
'content-type': contentType || 'application/json',
'Authorization': Taro.getStorageSync('token')
},
loading,
openErrTips
}
return Taro.request(requestParams)
}
get(url:string, data:any) {
return this.baseOptions({ url, method:'GET', data })
}
post(url:string, data:any) {
return this.baseOptions({ url, method:'POST', data })
}
}
export default new Request()
使用方式(笔者对接口模块区分接口管理)
- 在项目
pages
平级创建 api
文件夹(统一管理接口)
- 在
api
建立 index.ts
(导出接口)
import * as test from './test'
const Api = {
...test,
}
export default Api
- 在
api
建立测试模块接口列表 test.ts
import request from '@/service/index'
export const isTest = (url:string, data:any) => {
return request.post(url, data)
}
- 在
page
页面引入接口 import Api from '@/api/index'
并使用接口
Api.isTest({
id: 1,
name: 'Gavin',
loading: true,
loadingTitle: '自定义加载提示',
contentType: 'x-www-form-urlencoded',
openErrTips: true,
}).then((res:any) => {
}).catch((err:any) => {
})