当前位置: 首页 > 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.lryc.cn/news/603465.html

相关文章:

  • 自适应双门限的能量检测算法
  • 2025年中科院1区SCI-冬虫夏草优化算法Caterpillar Fungus Optimizer-附Matlab免费代码
  • 09 RK3568 Debian11 ES8388 模拟音频输出
  • 电磁兼容(EMC):整改案例(十三)屏蔽外壳开孔解决433MHz无线通信问题
  • vue3+vite 使用liveplayer加载视频
  • 【学习路线】游戏开发大师之路:从编程基础到独立游戏制作
  • BehaviorTree.Ros2 编译教程
  • java导入pdf(携带动态表格,图片,纯java不需要模板)
  • 前端基础之《Vue(26)—Vue3两种语法范式》
  • Spring MVC数据传递全攻略
  • 黑客哲学之学习笔记系列(一)
  • bash变量名不能有连字符
  • mac 字体遍历demo
  • SpringBoot 的@Repository 等注解的底层实现原理
  • PostgreSQL锁机制详解:从并发控制到死锁检测
  • 分布式时序数据库的特点解析
  • 网络原理 - TCP/IP(一)
  • 字节序详解
  • TCP/IP 传输层详解
  • 【dropdown组件填坑指南】鼠标从触发元素到下拉框中间间隙时,下拉框消失,怎么解决?
  • 分布式链路追踪的实现原理
  • 查询mac 安装所有python 版本
  • 【Spring AI 1.0.0】Spring AI 1.0.0框架快速入门(5)——Tool Calling(工具调用)
  • 解决mac下git pull、push需要输入密码
  • 学习Scala语言的最佳实践有哪些?
  • 使用 Django REST Framework 构建强大的 API
  • CVE-2022-46169漏洞复现
  • Mysql Connect -- 详解
  • Ollama安装及使用Ollama部署大模型
  • 51c大模型~合集161