当前位置: 首页 > news >正文

uniapp如何封装uni.request 全局使用

在 UniApp 中封装 uni.request 实现全局使用,可通过以下方案实现 统一配置、拦截器管理、错误处理和全局调用。以下是完整实现步骤:


一、基础封装方案(推荐)

1. 创建 http.js 请求封装模块
// utils/http.js// 基础配置
const BASE_URL = 'https://api.example.com'
const TIMEOUT = 15000// 请求队列(用于防止重复提交)
const pendingRequests = new Map()// 生成请求唯一标识
const generateReqKey = (config) => {return `${config.url}&${config.method}`
}// 核心请求函数
const request = (options) => {// 合并配置const config = {url: options.url,data: options.data || {},method: options.method || 'GET',header: {'Content-Type': 'application/json','X-Token': uni.getStorageSync('token') || '', // 自动携带token...(options.header || {}),},timeout: TIMEOUT,...options,}// 处理完整URLif (!config.url.startsWith('http')) {config.url = BASE_URL + config.url}// 防止重复请求拦截const reqKey = generateReqKey(config)if (pendingRequests.has(reqKey)) {return Promise.reject({ errMsg: '重复请求已取消' })}pendingRequests.set(reqKey, config)return new Promise((resolve, reject) => {uni.request({...config,success: (res) => {// 请求完成后移除队列pendingRequests.delete(reqKey)// 全局响应拦截器if (res.statusCode === 200) {// 业务状态码处理(示例)if (res.data.code === 401) {uni.navigateTo({ url: '/pages/login/login' })return reject(res.data)}resolve(res.data)} else {// HTTP状态码错误处理reject({ code: res.statusCode,message: `请求失败: ${res.errMsg}`})}},fail: (err) => {pendingRequests.delete(reqKey)// 网络错误统一处理reject({code: -1,message: '网络连接失败,请检查网络'})},complete: () => {// 可添加全局Loading关闭逻辑uni.hideLoading()}})})
}// 封装常用方法
const http = {get: (url, params = {}, options = {}) => {return request({url,data: params,method: 'GET',...options})},post: (url, data = {}, options = {}) => {return request({url,data,method: 'POST',...options})},put: (url, data = {}, options = {}) => {// 其他方法类似封装}
}export default http
2. 全局挂载(main.js)
// main.js
import Vue from 'vue'
import App from './App'
import http from '@/utils/http'// 挂载到Vue原型
Vue.prototype.$http = http// 挂载到全局uni对象
uni.$http = http// 如需使用this.$http调用
Vue.use({install(Vue) {Vue.config.globalProperties.$http = http}
})
3. 页面中使用
// 在.vue文件中
export default {methods: {async fetchData() {try {// GET请求const res1 = await this.$http.get('/user', { id: 123 })// POST请求const res2 = await uni.$http.post('/login', {username: 'admin',password: '123456'})} catch (err) {uni.showToast({ title: err.message, icon: 'none' })}}}
}

二、高级功能扩展

1. 添加拦截器系统
// 在http.js中添加
const interceptors = {request: [],response: []
}// 注册拦截器
http.addRequestInterceptor = (interceptor) => {interceptors.request.push(interceptor)
}http.addResponseInterceptor = (interceptor) => {interceptors.response.push(interceptor)
}// 修改request函数
const request = async (options) => {// ...原有代码...// 执行请求拦截器for (const interceptor of interceptors.request) {config = await interceptor(config) || config}return new Promise((resolve, reject) => {uni.request({...config,success: async (res) => {// 执行响应拦截器let response = resfor (const interceptor of interceptors.response) {response = await interceptor(response) || response}// ...后续处理...}})})
}
2. 使用示例(Token刷新)
// 在main.js中注册拦截器
http.addRequestInterceptor(config => {if (!config.url.includes('/refresh-token')) {const token = uni.getStorageSync('token')if (token) config.header['X-Token'] = token}return config
})http.addResponseInterceptor(async res => {if (res.data.code === 401) {// Token过期自动刷新const newToken = await http.post('/refresh-token', {refreshToken: uni.getStorageSync('refreshToken')})uni.setStorageSync('token', newToken)// 重新发送原请求return http(res.config)}return res
})

三、多端适配要点

  1. H5跨域处理

    // 开发环境代理配置 (vue.config.js)
    devServer: {proxy: {'/api': {target: 'https://api.example.com',changeOrigin: true,pathRewrite: { '^/api': '' }}}
    }
  2. 小程序域名白名单

    • 需在 manifest.json 配置合法域名

    "mp-weixin": {"appid": "xxx","setting": {"urlCheck": false},"permission": {"scope.userLocation": {"desc": "需要获取您的位置信息"}},"requiredPrivateInfos": ["getLocation"]
    }
  3. App端证书校验

    // 仅iOS需要处理
    if (uni.getSystemInfoSync().platform === 'ios') {config.sslVerify = false // 关闭SSL验证(仅测试环境)
    }

四、最佳实践建议

  1. 全局Loading控制

    // 请求计数
    let requestCount = 0http.addRequestInterceptor(config => {if (!config.hideLoading) {requestCount === 0 && uni.showLoading({ title: '加载中', mask: true })requestCount++}return config
    })http.addResponseInterceptor(response => {if (!response.config.hideLoading) {requestCount--requestCount === 0 && uni.hideLoading()}return response
    })
  2. 请求重试机制

    const retryRequest = (config, retry = 3) => {return request(config).catch(err => {return retry > 0 ? retryRequest(config, retry - 1) : Promise.reject(err)})
    }
  3. TypeScript支持

    // http.d.ts
    declare module '@vue/runtime-core' {interface ComponentCustomProperties {$http: {get<T = any>(url: string, params?: object): Promise<T>;post<T = any>(url: string, data?: object): Promise<T>;}}
    }

封装优势

  • 统一管理所有网络请求逻辑

  • 自动处理 token 和权限认证

  • 支持多端差异化配置

  • 提供拦截器实现业务解耦

  • 内置防重复提交和错误重试机制

http://www.dtcms.com/a/304252.html

相关文章:

  • qt webengine播放视频
  • VS+Qt中使用QCustomPlot绘制曲线标签(附源码)
  • 002 TrafficGenerator 类详解
  • FCN语义分割算法原理与实战
  • 八股训练营 40 天心得:一场结束,也是一场新的开始
  • 力扣热题100--------240.搜索二维矩阵
  • LeetCode热题100——46. 全排列
  • 研电赛-基于GD32的纳型无人机AI追踪系统1
  • vue相关的拖拉拽官网
  • minio安装 windows系统
  • C语言第六章函数递归
  • Linux文件归档和备份
  • Qt 多线程网络编程实战
  • iOS 能耗·电池·电量监控实战指南:如何全面查看与优化 App 电能消耗
  • VTK开发笔记(一):VTK介绍,Qt5.9.3+VS2017x64+VTK8.2编译
  • AI驱动的浏览器自动化革命:Claude Code + BrowserCat MCP深度实践指南
  • 【MySQL学习|黑马笔记|Day2】SQL|DML、DGL、DCL,函数,约束
  • Python 打造 Excel 到 JSON 转换工具:从开发到打包全攻略
  • Java后端开发数据校验工作
  • Qt 嵌入式开发环境搭建
  • .NET测试平台Parasoft dotTEST在汽车电子行业的核心功能及应用
  • PCIE4.0/5.0/DDR4/DDR5使用以及布局布线规则-集萃
  • python cli命令 cli工具命令 自定义cli命名 开发 兼容 window、mac、linux,调用示例
  • ath12k_mac_op_tx到数据包发送的完整调用路径
  • Java把word转HTML格式
  • Hexo+Shoka 博客搭建保姆级教程
  • 鸿蒙Harmony-自定义List组件,解决List组件手势滑动点击卡住问题
  • Android JNI 语法全解析:从基础到实战
  • 预过滤环境光贴图制作教程:第二步 - 生成环境贴图图集
  • 音频算法基础(语音识别 / 降噪 / 分离)