uni-app后端接口请求(封装)

提示:添加请求拦截器及封装请求方法

文章目录

  • 前言
  • 一、

    (1) 服务端概述 开发服务器 生产服务器

    小程序端调用, 请求头中 header 中添加: source-client: miniapp

    用户登录成功后, 调用需要 token 的接口, 无 token 或者 token 错误, 响应状态码是 401

    服务端概述 开发服务器 生产服务器
    参数名称位置类型必填说明
    source-clientheaderstring示例值: miniapp 代表小程序端, app 代表 App 端
    Authorizationheaderstring示例值: Authorization: token

(1) uni-app 中的拦截器语法

// STRING: 需要拦截的api名称, 比如 request、uploadFile 等
// OBJECT: 配置对象, 比如 invoke, 表示调用 api 后发送请求前执行的方法
uni.addInterceptor(STRING, OBJECT)

(2)实现请求拦截器中的逻辑

请求拦截器: 请求基准地址、超时时间、添加请求头标识 (Authorization、source-client)

// src/utils/request.ts
import { useMemberStore } from '@/stores'

// 请求基准地址
const baseURL = 'https://pcapi-xiaotuxian-front-devtest.itheima.net'

// 拦截器配置对象
const httpInterceptor = {
  // 执行请求前触发
  invoke(options: UniApp.RequestOptions) {
    // 如果请求路径不是以 http 开头的
    if (!options.url.startsWith('http')) {
      // 将 url 参数拼接为完整路径
      options.url = baseURL + options.url
    }
    // 更改请求超时时间, 该时间默认为 10s, 时间以毫秒为单位
    options.timeout = 3000
    // 添加请求头标识
    options.header = {
      ...options.header,
      'source-client': 'miniapp',
    }

    // 获取用于存储登录用户信息的 store 对象
    const memberStore = useMemberStore()
    // 获取用户登录凭据
    const token = memberStore.profile?.token
    // 如果 token 存在
    if (token) {
      // 将用户登录凭据添加到请求头中
      options.header.Authorization = 'Bearer ' + token
    }
  },
}

// 对 request 方法进行拦截处理
uni.addInterceptor('request', httpInterceptor)
// 对 uploadFile 方法进行拦截处理
uni.addInterceptor('uploadFile', httpInterceptor)

(3) 封装请求函数并实现响应拦截器中的逻辑

要求函数返回 Promise, 方便函数的调用者使用 async await。

响应成功: 提取关键数据、为服务端返回数据添加类型

响应失败: 网络错误、401 错误、其他错误(服务端返回什么就提示什么)

 ① 封装返回 Promise 的请求函数并提取关键数据

// src/utils/request.ts
// 封装用于发送请求的方法
export const request = (options: UniApp.RequestOptions) => {
  return new Promise((resolve, reject) => {
    uni.request({
      ...options,
      success: (response) => {
        resolve(response.data)
      },
    })
  })
}

② 为服务端返回数据添加类型

// 声明服务端返回的数据类型
interface Data<T> {
  // 业务状态
  code: string
  // 提示消息
  msg: string
  // 数据
  result: T
}

// 封装用于发送请求的方法
export const request = <T>(options: UniApp.RequestOptions) => {
  // Promise 接收泛型参数, 用于标注成功状态下的数据的类型, 即调用 resolve 方法时传递的参数的类型
  return new Promise<Data<T>>((resolve, reject) => {
    uni.request({
      ...options,
      success: (response) => {
        // 获取服务端返回的响应
        const data = response.data as Data<T>
        // 将 Promise 的状态设置为成功, 并传递服务端返回的响应
        resolve(data)
      },
    })
  })
}

③ 处理响应失败的情况

/ 封装用于发送请求的方法
export const request = <T>(options: UniApp.RequestOptions) => {
  // Promise 接收泛型参数, 用于标注成功状态下的数据的类型, 即调用 resolve 方法时传递的参数的类型
  return new Promise<Data<T>>((resolve, reject) => {
    uni.request({
      ...options,
      success: (response) => {
        // 获取服务端返回的响应
        const data = response.data as Data<T>
        // 注意: uni.request 方法没有处理响应状态码
        // 也就是说只要服务端有响应, 无论该响应是成功状态还是失败状态都会执行 success 函数
        // 所以此处我们需要手动判断状态下, 然后决定是执行请求成功的逻辑还是执行请求失败的逻辑
        // 获取响应状态码
        const statusCode = response.statusCode
        // 如果请求状态是成功的
        if (statusCode >= 200 && statusCode < 300) {
          // 执行请求成功之后的逻辑
          // 将 Promise 的状态设置为成功, 并传递服务端返回的响应
          resolve(data)
          // 如果请求状态是失败的, 且状态码为 401
        } else if (statusCode === 401) {
          // 401 错误
          const memberStore = useMemberStore()
          // 清空用户信息
          memberStore.clearProfile()
          // 跳转到登录页面
          uni.navigateTo({ url: '/pages/login/login' })
          // 将 promise 的状态设置为失败
          reject(response)
          // 如果请求状态为失败的, 且为通用错误
        } else {
          // 通用错误
          uni.showToast({ icon: 'none', title: data.msg || '请求错误' })
          // 将 promise 的状态设置为失败
          reject(response)
        }
      },
      fail: (error) => {
        // 只有网络错误, 请求没有发出去才会执行当前函数
        uni.showToast({ icon: 'none', title: '网络错误, 请换个网络试试' })
        // 将 promise 的状态设置为失败
        reject(error)
      },
    })
  })
}

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
对于uni-app中的跨域问题,可以通过以下几种方式解决: 1. 使用代理:在uni-app的配置文件vue.config.js中配置proxyTable,将请求代理到后端接口。示例代码如下: ```javascript module.exports = { devServer: { proxy: { '/api': { target: 'http://example.com', // 后端接口地址 changeOrigin: true, pathRewrite: { '^/api': '' } } } } } ``` 2. 后端设置CORS:在后端接口中设置CORS(跨域资源共享)头部信息,允许前端的跨域请求。示例代码如下(使用Node.js Express框架): ```javascript const express = require('express'); const app = express(); // 设置CORS头部信息 app.use((req, res, next) => { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); next(); }); // 处理接口请求 app.get('/api/example', (req, res) => { // 处理业务逻辑 res.json({ message: 'Hello World' }); }); // 启动服务器 app.listen(3000, () => { console.log('Server is running on port 3000'); }); ``` 3. JSONP请求:如果后端接口支持JSONP,可以使用uni-app中的jsonp插件进行跨域请求。示例代码如下: ```javascript import jsonp from 'jsonp'; // 发起JSONP请求 jsonp('http://example.com/api', { param: 'callback' }, (err, data) => { if (err) { console.error(err); } else { console.log(data); } }); ``` 以上是解决uni-app中跨域问题的常见方法,选择合适的方式进行解决即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值