微信小程序request/uploadFile请求封装

737 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

前言

使用微信小程序开发的项目,其业务功能一般是比较简单/单一的,一个项目根据不同业务可能还会开发不同的小程序,因此封装一个统一的request请求加快开发还是很有必要的。

wx.request封装

因为小程序是以openId识别用户的,所以每个请求自动添加openId,请求时显示一个Loading等待框,请求成功返回需要的数据,不成功全局弹窗提示异常。

  • 每个请求自动添加openid参数
  • 请求时显示Loading提示框(可配置)
  • 请求成功,业务状态码200,解析最后的result结果返回
  • http请求非200或业务非200,全局message提示报错

wx.uploadFile 封装

这里是针对上传图片的封装。图片上传至文件存储服务器并获取图片存储链接

  • 可同时上传多张图片
  • 请求时显示Loading提示框
  • 请求成功,返回包含图片链接的数组
  • http请求非200或业务非200,全局message提示报错

虽然功能简单,但对于大多数业务简单的中小程序已经足够用了。

封装效果

网络请求调用http.post(api.urlxx,{}).then(),默认显示Loading,不显示的话,使用http.post(api.urlxx,{},false).then()

//引用文件,请根据实际路径修改
import api from '../../../utils/api.js'
import http from '../../../utils/httpUtils.js'

http.post(
  api.getUserInfo, //请求地址
  {'x': ''}        //请求参数
).then(res => {
  //请求成功
}, res => {
  //请求异常
})

上传图片调用http.upload(xxx).then()

//引用文件,请根据实际路径修改
import api from '../../../utils/api.js'
import http from '../../../utils/httpUtils.js'

//imgList为数组['xx','xx']形式的图片链接
let imgList = this.data.imgList
//上传图片,结果更新到this.data.imgList
http.upload(imgList).then(res=>{
  //图片上传成功获取到链接后,调用业务接口关联链接
  http.post(
    api.getUserInfo, //请求地址
    {'x': '',
    'pictures':JSON.stringify(this.data.imgList)}//上传结果更新到imgList里了
  ).then(res => {
    //请求成功
  }, res => {
    //请求异常
  })
},res=>{
  console.log(res)
})

具体实现

目录结构: uTools_1655354236168.png

api.js文件: 请求地址url统一放在这个文件里,每次新增接口,只需在这个文件添加一个链接即可,其他文件不用修改。

// const BASE_URL = 'http://192.168.43.113:80/xxxx/' //生产服务器地址
const BASE_URL = 'https://xxx.xx.xx/xxxx/' //正式服务器地址

module.exports = {
  token: BASE_URL + 'token',//获取token
  login: BASE_URL + 'login',//登录
}

httpUtils.js文件:封装了wx.request/wx.uploadFile,需要说明的是,服务器的每一个接口响应结构为如下形式:

{
'msg':'',
'code':200,
'data':xx
}

具体httpUtils.js代码

import api from 'api.js';

//get请求
function get(url, data = {}, load = true) {
  let header = this._header = {
    "Content-Type": "application/json"
  }
  return sendRequest(url, data, header, 'GET', load)
}
/**
 * 主要的调用入口
 * @param {请求地址} url 
 * @param {请求参数} data 
 * @param {是否显示提示框} load 
 */
function post(url, data = {}, load = true) {
  let header = {
    "Content-Type": "application/x-www-form-urlencoded"
  }
  return sendRequest(url, data, header, 'POST', load)
}

let openId = wx.getStorageSync('openId')

//网络请求的工具类
function sendRequest(url, data = {}, header = this._header, method = 'get', load = true) {

  if (!openId) {
    //从存储中取出openId,需要在app.js里事先保存好
    openId = wx.getStorageSync('openId')
  }
  //如果data里有指定了openId
  if (!openId && data.openId) {
    openId = data.openId
  }

  console.log(url, data)

  return new Promise((reslove, reject) => {
    if (load) {
      wx.showLoading({
        title: '请求中',
        mask: true
      });
    }

    data.openID = openId
    wx.request({
      url: url,
      data: data,
      method: method,
      header: header,
      dataType: 'json', //默认也是json的,这里可以改成其他的
      success: function (res) {
        console.log(res)
        if (load) {
          wx.hideLoading({
            success: (res) => {},
          })
        }
        if (res.statusCode === 200) {
          if (res.data.code === 200) { //业务接口处理正常
            console.log(res.data.data)
            reslove(res.data.data)
          } else {
            console.log(res.data)
            reject(res.data)
            if (res.data.code !== 10000) { //未传入openid,根据实际业务修改
              show(res.data.msg)
            }
          }
        } else {
          console.log(res)
          reject(res)
          show('服务器响应异常,CODE:' + res.statusCode)
        }
      },
      fail: function (res) {
        if (load) {
          wx.hideLoading({
            success: (res) => {},
          })
        }
        console.log(res)
        reject(res)
        show('请求异常')
      },
      complete() {}
    })
  })
}

/**
 * 
 * @param {需要上传的文件地址} tempFilePaths 
 * @param {额外参数} formData 
 * @param {文件服务器地址} url 
 */
function upload(tempFilePaths, formData = {}, url = api.serverUpload) {
  return new Promise((presolve, preject) => {
    if ({}.toString.call(tempFilePaths) != '[object Array]') {
      throw new TypeError(`上传图片参数 tempFilePaths 类型错误!`)
    }
    //路径数组为空时  不上传
    if (tempFilePaths.length == 0) {
      presolve([])
      return
    }
    wx.showLoading({
      title: '上传图片中...',
      mask: true
    });
    let uploads = []
    let index = 0
    tempFilePaths.forEach((item, i) => {
      let local = false
      if (item.includes('http://tmp') || item.includes('wxfile://tmp')) { //当前连接是用户选择的本地图片连接
        local = true
      }
      if (item.includes('xxxx')) {//如果文件地址是非本地的文件,就不用上传了
        local = false
      }
      if (local) {

        uploads[index++] = new Promise((reslove, reject) => {
          formData.openID = openId
          wx.uploadFile({
            filePath: item,
            name: 'file',
            url: url,
            formData: formData,
            success(res) {

              if (res.statusCode === 200) {
                res.data = JSON.parse(res.data)
                if (res.data.code === 200) { //接口处理正常
                  console.log(res.data.data)
                  tempFilePaths[i] = res.data.data.url
                  show(res.data.msg)
                  reslove(res.data.data.url)
                } else {
                  reject(res.data)
                  show(res.data.msg)
                }
              } else {
                reject(res)
                show('服务器响应异常,CODE:' + res.statusCode)
              }
            },
            fail(res) {
              reject(res)
              show('请求异常' + JSON.stringify(res))
            },
          })
        })
      }

    });
    if (uploads.length == 0) {
      presolve([])
      wx.hideLoading()
      return
    }

    Promise.all(uploads).then(res => {
      console.log(res)
      //图片上传完成
      presolve(res)
      wx.hideLoading()
    }).catch(err => {
      preject(err)
      wx.hideLoading()
      wx.showToast({
        title: '上传失败请重试',
        icon: 'none'
      })
    })
  })
}

function show(msg) {
  wx.showToast({
    title: msg,
    icon: "none",
    duration: 3000
  })
}

//这里暴露方法就行了
export default {
  get,
  post,
  upload,
}

以上大概就是对微信的request以及uploadFile请求的封装以及调用

有好的建议,请在下方输入你的评论,感谢您的阅读