Skip to content

flyio 在小程序的网络请求封装

项目地址:https://github.com/wendux/fly(又名 flyio)
文档/示例:见仓库 README
关联清单:https://github.com/justjavac/awesome-wechat-weapp

Fly 是一个支持浏览器、Node、Weex、RN、微信小程序等多端的 HTTP 请求库,API 风格与 axios 类似,具备拦截器、适配器、Promise 等特性,适合在小程序中做统一的数据层封装。

🎯 文章目标

  • 在小程序中正确初始化 flyio
  • 实现统一拦截器、错误处理与 Token 刷新
  • 封装请求实例并在多端中复用

📦 安装与引入

bash
npm i flyio -S
# 在微信开发者工具中:工具 -> 构建 npm

在微信小程序端使用专属适配器(wx):

js
// src/services/http.js
import Fly from 'flyio/dist/npm/wx'   // 关键:小程序端适配器
const fly = new Fly()

fly.config.baseURL = 'https://api.example.com'
fly.config.timeout = 10000
fly.config.headers = { 'Content-Type': 'application/json' }

// 请求拦截器
fly.interceptors.request.use((request) => {
  const token = wx.getStorageSync('token')
  if (token) request.headers.Authorization = `Bearer \${token}`
  // 可在此注入 traceId、locale 等
  return request
})

// 响应拦截器
fly.interceptors.response.use(
  (response) => {
    // 统一处理后端响应格式
    const { data } = response
    if (data && data.code === 0) return data.data
    // 非业务成功
    return Promise.reject({ code: data?.code || -1, message: data?.message || '业务错误' })
  },
  (error) => {
    // 网络/超时等错误
    const status = error?.status || 0
    return Promise.reject({ code: status, message: '网络异常或超时', raw: error })
  }
)

export default fly

🔁 重试与指数退避(可选)

js
// 简易重试:对网络错误/超时做至多 2 次重试
function withRetry(fly, times = 2, delay = 300) {
  fly.interceptors.response.use(
    (res) => res,
    async (err) => {
      if (!times) return Promise.reject(err)
      const retryable = !err.code || err.code === 0 // 无状态或网络错误
      if (!retryable) return Promise.reject(err)
      await new Promise(r => setTimeout(r, delay))
      times -= 1
      return fly.request(err.request) // 复用原请求
    }
  )
}
withRetry(fly, 2, 400)

🔐 Token 过期与刷新(队列化示例)

js
let isRefreshing = false
let queue = []

fly.interceptors.response.use(
  (res) => res,
  async (err) => {
    if (err.code === 401) {
      if (!isRefreshing) {
        isRefreshing = true
        try {
          const newToken = await refreshToken() // 自行实现刷新逻辑
          wx.setStorageSync('token', newToken)
          queue.forEach(cb => cb(newToken))
          queue = []
          return fly.request(err.request) // 重放失败请求
        } finally {
          isRefreshing = false
        }
      }
      // 将请求放入队列,等待刷新结果
      return new Promise(resolve => {
        queue.push(() => {
          err.request.headers.Authorization = `Bearer \${wx.getStorageSync('token')}`
          resolve(fly.request(err.request))
        })
      })
    }
    return Promise.reject(err)
  }
)

🧩 在 Taro/uni-app 中使用

  • Taro:可在 Taro 项目中直接引入 flyio/dist/npm/wx,但 Taro 已内置 Taro.request,如需统一多端建议评估是否直接用 Taro.request
  • uni-app:在 mp-weixin 端使用 flyio/dist/npm/wx,在 H5 端可用 flyio/dist/npm/fly;也可统一用 uni.request,通过自封装保持一致接口

🧪 常见问题

  • “找不到模块”或构建失败:确保执行了“构建 npm”,并清理开发者工具缓存后重试
  • 跨域/证书:小程序网络层限制与域名白名单,需在小程序后台配置 request 合法域名
  • 超时/重试失效:检查拦截器返回值与 Promise.reject/resolve 链是否被提前消费

✅ 适用场景

  • 需要 axios 风格 API 与拦截器体系
  • 多端统一的请求封装(浏览器/小程序/Node)
  • 需要复杂的登录态管理与请求重放

🔗 参考

📊 总结

flyio 为小程序带来熟悉的 axios 式体验。合理设计拦截器与错误治理、在多端适配合适的 adapter,即可构建可维护、可观测的统一数据访问层。