微信小程序开发,wx.request网络请求封装

1. 官方文档指南

  1. 网络请求:https://developers.weixin.qq.com/miniprogram/dev/api/network/request/wx.request.html

2. 使用教程

RequestTask wx.request(Object object)

功能描述
发起 HTTPS 网络请求。使用前请注意阅读相关说明。

参数
Object object

属性 类型 默认值 必填 说明
url string 开发者服务器接口地址
data string/object/ArrayBuffer 请求的参数
header Object 设置请求的header,header中不能设置Referer。默认为 application/json
timeout number 超时间,单位为毫秒,默认值为 60000
method string GET HTTP请求方法
dataType string gson 返回的数据格式
responseType string text 响应的数据类型
success function 接口调用成功的回调函数
fail function 接口调用失败的回调函数
complete function 接口调用结束的回调函数(调用成功、失败都会执行)

object.success 回调函数

参数
Object res

属性 类型 说明
data string/Object/Arraybuffer 开发者服务器返回的数据
statusCode number 开发者服务器返回的 HTTP 状态码
header Object 开发者服务器返回的 HTTP Response Header
cookies Array 开发者服务器返回的 cookies,格式为字符串数组
profile Object 网络请求过程中的一些调试信息,查看详细说明
exception Object 网络请求过程中的异常信息,例如httpdns重试等
useHttpDNS boolean 最终请求是否使用了HttpDNS(仅当enableHttpDNS传true时返回此字段)

object.fail 回调函数

参数
Object err

属性 类型 说明
errMsg String 错误信息
errno Number Errno 错误码,errno错误码的详细说明参考 Errno 错误码

更多详情请查看官方文档 | 更多详情请查看官方文档 | 更多详情请查看官方文档

3. 代码封装

  1. 新建一个包,取名叫net ,在包下面新建request.js文件,项目结构示意图如下:
    在这里插入图片描述
  2. 在request.js 定义 WxRequest类

class WxRequest {
    
    
  // 定义实例属性,用来设置默认请求参数
  defaults = {
    
    
    baseURL: '', // 请求基准地址
    url: '', // 接口的请求路径
    data: null, // 请求参数
    method: 'GET', // 默认的请求方法
    // 请求头
    header: {
    
    
      'Content-type': 'application/json' // 设置数据的交互格式
    },
    timeout: 60000, // 默认的超时时长,小程序默认的超时时长是 1 分钟
    isLoading: true // 控制是否使用默认的 loading,默认值是 true 表示使用默认的 loading
  }

  // 定义拦截器对象
  interceptors = {
    
    
    // 请求拦截器
    request: (config) => config,

    // 响应拦截器
    response: (response) => response
  }

  // 定义数组队列,用来存储请求队列、存储请求标识
  queue = []

  // constructor 用于创建和初始化类的属性以及方法
  constructor(params = {
     
     }) {
    
    
    // 注意:需要传入的参数,覆盖默认的参数,因此传入的参数需要放到最后
    this.defaults = Object.assign({
    
    }, this.defaults, params)
  }

  /**
   * @description request 实例方法发送网络请求,接收一个对象类型的参数
   * @param {*} options 属性值和 wx.request() 方法调用时传递的参数保持一致
   * @returns Promise
   */
  request(options) {
    
    
    // 如果有新的请求,就清除上一次的定时器
    this.timerId && clearTimeout(this.timerId)

    // 合并完整的请求地址
    options.url = this.defaults.baseURL + options.url

    // 合并请求参数:调用实例方法时传入的覆盖默认的以及实例配置的
    options = {
    
     ...this.defaults, ...options }

    // 控制 loading 的显示与隐藏
    if (options.isLoading && options.method !== 'UPLOAD') {
    
    
      this.queue.length === 0 && wx.showLoading()
      this.queue.push('request')
    }

    // 在请求发送之前,调用请求拦截器,新增和修改请求参数
    // 请求拦截器内部,会将新增和修改以后的参数返回
    options = this.interceptors.request(options)

    // 需要使用 Promise 封装 wx.request,处理异步请求
    return new Promise((resolve, reject) => {
    
    
      // 如果 method 等于 UPLOAD 说明需要调用 wx.uploadFile() 方法
      // 否则调用的是 wx.request() 方法
      if (options.method === 'UPLOAD') {
    
    
        wx.uploadFile({
    
    
          ...options,

          success: (res) => {
    
    
            // 需要将服务器返回的 JSON 字符串 通过 JSON.parse 转成对象
            res.data = JSON.parse(res.data)

            // 合并参数
            const mergeRes = Object.assign({
    
    }, res, {
    
    
              config: options,
              isSuccess: true
            })

            resolve(this.interceptors.response(mergeRes))
          },

          fail: (err) => {
    
    
            // 合并参数
            const mergeErr = Object.assign({
    
    }, err, {
    
    
              config: options,
              isSuccess: false
            })

            reject(this.interceptors.response(mergeErr))
          }
        })
      } else {
    
    
        wx.request({
    
    
          ...options,

          // 当接口调用成功时会触发 success 回调函数
          success: (res) => {
    
    
            // 合并请求参数,方便进行代码调试
            // 追加 isSuccess 属性,是为了标识响应拦截器是 success 调用还是 fail 调用
            const mergeRes = Object.assign({
    
    }, res, {
    
    
              config: options,
              isSuccess: true
            })
            resolve(this.interceptors.response(mergeRes))
          },

          // 当接口调用失败时会触发 fail 回调函数
          fail: (err) => {
    
    
            // 合并请求参数,方便进行代码调试
            // 追加 isSuccess 属性,是为了标识响应拦截器是 success 调用还是 fail 调用
            const mergeErr = Object.assign({
    
    }, err, {
    
    
              config: options,
              isSuccess: false
            })
            reject(this.interceptors.response(mergeErr))
          },

          // 接口调用结束的回调函数(调用成功、失败都会执行)
          complete: () => {
    
    
            // 如果需要显示 loading ,那么就需要控制 loading 的隐藏
            if (options.isLoading) {
    
    
              // 在每一个请求结束以后,都会执行 complete 回调函数
              // 每次从 queue 队列中删除一个标识
              this.queue.pop()

              // 解决并发请求,loading 闪烁问题
              this.queue.length === 0 && this.queue.push('request')

              //解决并发请求,loading 闪烁问题
              this.timerId = setTimeout(() => {
    
    
                this.queue.pop()

                this.queue.length === 0 && wx.hideLoading()

                clearTimeout(this.timerId)
              }, 1)
            }
          }
        })
      }
    })
  }

  /**
   * @description 封装 GET 实例方法
   * @param {*} url 请求地址
   * @param {*} data 请求参数
   * @param {*} config 其他请求配置项
   * @returns Promise
   */
  get(url, data = {
    
    }, config = {
    
    }) {
    
    
    // 需要调用 request 请求方法发送请求,只需要组织好参数,传递给 request 请求方法即可
    // 当调用 get 方法时,需要将 request 方法的返回值 return 出去
    return this.request(Object.assign({
    
     url, data, method: 'GET' }, config))
  }

  /**
   * @description 封装 DELETE 实例方法
   * @param {*} url 请求地址
   * @param {*} data 请求参数
   * @param {*} config 其他请求配置项
   * @returns Promise
   */
  delete(url, data = {
    
    }, config = {
    
    }) {
    
    
    return this.request(Object.assign({
    
     url, data, method: 'DELETE' }, config))
  }

  /**
   * @description 封装 POST 实例方法
   * @param {*} url 请求地址
   * @param {*} data 请求参数
   * @param {*} config 其他请求配置项
   * @returns Promise
   */
  post(url, data = {
     
     }, config = {
     
     }) {
    
    
    return this.request(Object.assign({
    
     url, data, method: 'POST' }, config))
  }

  /**
   * @description 封封装 PUT 实例方法
   * @param {*} url 请求地址
   * @param {*} data 请求参数
   * @param {*} config 其他请求配置项
   * @returns Promise
   */
  put(url, data = {
     
     }, config = {
     
     }) {
    
    
    return this.request(Object.assign({
    
     url, data, method: 'PUT' }, config))
  }

  /**
   * @description 处理并发请求
   * @param  {...promise} promise 传入的每一项需要是 Promise
   * @returns Promise
   */
  all(...promise) {
    
    
    // 那么展开运算符会将传入的参数转成数组
    return Promise.all(promise)
  }

  /**
   * @description upload 实例方法,用来对 wx.uploadFile 进行封装
   * @param {*} url 文件的上传地址、接口地址
   * @param {*} filePath 要上传的文件资源路径
   * @param {*} name 文件对应的 key
   * @param {*} config 其他配置项
   */
  upload(url, filePath, name = 'file', config = {
    
    }) {
    
    
    return this.request(
      Object.assign({
    
     url, filePath, name, method: 'UPLOAD' }, config)
    )
  }
}

//记得要导出
export default WxRequest

4. 如何使用?

  1. test.wxml
<!--pages/test/test.wxml-->
<view class="container-demo">
		<button type="primary" size="mini" bind:tap="httpGet" >网络请求测试</button>
		 <text>{
    
    {
    
    userInfo}}</text>
</view>

  1. test.wxss
/* pages/test/test.wxss */

.container-demo{
    
    
	display: flex;
	padding: 100rpx;
	flex-direction: column;
	gap: 20rpx;
	
}
  1. test.js
// pages/test/test.js

//导入网络模块
import http from '../../net/http'

Page({
    
    

  /**
   * 页面的初始数据
   */
  data: {
    
    
    userInfo: '默认用户信息暂无'
  },


  //第一种写法(推荐使用 await + async的形式使用)
  async httpGet() {
    
    
    const res = await http.get('/login',
     {
    
    'username': 'yihuangxing','password': '123456'}, 
     {
    
     isLoading: true })

    this.setData({
    
    
      userInfo: JSON.stringify(res.data)
    })
  },

  //第二种写法
  // httpGet() {
    
    
  //   http.get('/login',
  //   {'username':'yihuangxing','password': 123456},
  //   {isLoading:true})
  //   .then((res)=>{
    
    
  //       this.setData({
    
    
  //         userInfo: JSON.stringify(res.data)
  //       })
  //   })
  // },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    
    

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {
    
    

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {
    
    

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {
    
    

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {
    
    

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {
    
    

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {
    
    

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {
    
    

  }
})

温馨提示:
调用方法,获取响应数据 形式用两种:

  1. 使用then拿到响应结果
  2. 使用 async + await 拿到响应结果 (推荐使用)

5. 运行效果图

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/jky_yihuangxing/article/details/141630495