uniapp请求接口封装
前言:
uniapp请求接口封装
实现效果:
实现代码:
核心:request.js
// 是否为本地环境
const isDev = process.env.NODE_ENV === 'development'// 默认配置
const defaultOptions = {baseURL: isDev ? 'https://xxxxx' : '',timeout: 15000, // 请求接口超时时间dataType: 'json',header: {'Content-Type': 'application/json'},showErrToast: true,loading: true
}// 请求核心方法
const request = async (method, url, data = {}, customOptions = {}) => {// 合并配置const options = {...defaultOptions,method,data,}// 请求接口地址处理,如果传来http/https的直接用传来的地址if( url.startsWith('http') || url.startsWith('https')){options.url = url} else {options.url = `${defaultOptions.baseURL}${url}`}// 请求拦截const token = uni.getStorageSync('token')if (token) {options.header.Authorization = `Bearer ${token}`}// 显示 Loadingif (options.loading) {uni.showLoading({ title: '加载中...', mask: true })}// 自定义headerif(customOptions.header){options.header = Object.assign(options.header,customOptions.header)}return new Promise((resolve, reject) => {uni.request({...options,success: (res) => {try {const processedRes = responseInterceptor(res)resolve(processedRes.data)} catch (error) {reject(error)}},fail: (err) => {console.error('[Request Fail]', err)if (options.showErrToast) {uni.showToast({ title: err.errMsg || '请求失败', icon: 'none' })}reject(err)},complete: () => {options.loading && uni.hideLoading()}})})
}// 响应拦截器
const responseInterceptor = (res) => {console.log(`[Response] ${res.statusCode}`, res)// HTTP 状态码错误if (res.statusCode < 200 || res.statusCode >= 300) {throw new Error(`接口请求失败 Error: ${res.statusCode}`)}// 业务状态码处理if (res.data?.code === 401) {handleUnauthorized()throw new Error('登录状态已过期')}return res
}// 401 处理封装
const handleUnauthorized = () => {const pages = getCurrentPages()const currentPage = pages[pages.length - 1]const redirectUrl = currentPage ? `/${currentPage.route}` : '/'uni.removeStorageSync('token')uni.removeStorageSync('userInfo')uni.showToast({title: '登录已过期',icon: 'none',duration: 800})setTimeout(() => {// 关闭所有界面,回到登录页面uni.reLaunch({url: `/pages/login/index?redirect=${encodeURIComponent(redirectUrl)}` })}, 800)
}// 快捷方法
export const get = (url, data, options) => request('GET', url, data, options)
export const post = (url, data, options) => request('POST', url, data, options)
export const put = (url, data, options) => request('PUT', url, data, options)
export const del = (url, data, options) => request('DELETE', url, data, options)// 文件上传优化
export const uploadFile = (url, filePath, options = {}) => {let fullUrl = ''// 请求接口地址处理,如果传来http/https的直接用传来的地址if( url.startsWith('http') || url.startsWith('https')){fullUrl = url} else {fullUrl = `${defaultOptions.baseURL}${url}`}return new Promise((resolve, reject) => {uni.uploadFile({url: fullUrl,filePath,name: 'file', // 参数字段header: {Authorization: uni.getStorageSync('token') ? `Bearer ${uni.getStorageSync('token')}` : '',...options.header},success: (res) => {if (res.statusCode === 200) {try {resolve(JSON.parse(res.data))} catch (e) {resolve(res.data)}} else {reject(new Error(`上传失败:${res.errMsg}`))}},fail: reject})})
}// 文件下载
export const downloadFile = (url, options = {}) => {const fullUrl = url.startsWith('http') || url.startsWith('https') ? url : `${API_URL}${url}`return uni.downloadFile({url: fullUrl,...options})
}