评论

如何实现一个简单的http请求的封装

一个简单的http请求封装

好久没发文章了,最近浏览社区看到比较多的请求封装,以及还有在使用原始请求的童鞋。为了减少代码,提升观赏性,我也水一篇吧,希望对大家有所帮助。

默认请求方式,大家每次都这样一些写相同的代码,会不会觉得烦,反正我是觉得头大 😂

wx.request({
  url: 'test.php', //仅为示例,并非真实的接口地址
  data: {
    x: '',
    y: ''
  },
  header: {
    'content-type': 'application/json' // 默认值
  },
  success (res) {
    console.log(res.data)
  }
})

来,进入正题吧,把这块代码封装下。

首先新建个request文件夹,内含request.js
代码如下:

/**
 * 网络请求封装
 */
import config from '../config/config.js'
import util from '../util/util.js'

// 获取接口地址
const _getPath = path => (config.DOMAIN + path)

// 封装接口公共参数
const _getParams = (data = {}) => {
  const timestamp = Date.now()  //时间戳
  const deviceId = Math.random() //随机数
  const version = data.version || config.version //当前版本号,自定或者取小程序的都行
  const appKey = data.appKey || config.appKey //某个小程序或者客户端的字段区分
  //加密下,防止其他人随意刷接口,加密目前采用的md5,后端进行校验,这段里面的参数你们自定,别让其他人知道就行,我这里就是举个例子
  const sign = data.sign || util.md5(config.appKey + timestamp + deviceId)
  return Object.assign({}, {
    timestamp,
    sign,
    deviceId,
    version,
    appKey
  }, data)
}

// 修改接口默认content-type请求头
const _getHeader = (headers = {}) => {
  return Object.assign({
    'content-type': `application/x-www-form-urlencoded`
  }, headers)
}
// 存储登录态失效的跳转
const _handleCode = (res) => {
  const {statusCode} = res
  const {msg, code} = res.data
  // code为 4004 时一般表示storage里存储的token失效或者未登录
  if (statusCode === 200 && (code === 4004)) {
    wx.navigateTo({
      url: '/pages/login/login'
    })
  }
  return true
}

/**
 * get 请求, post 请求
 * @param {String} path 请求url,必须
 * @param {Object} params 请求参数,可选
 * @param {String} method 请求方式 默认为 POST
 * @param {Object} option 可选配置,如设置请求头 { headers:{} }
 *
 * option = {
 *  headers: {} // 请求头
 * }
 *
 */

export const postAjax = (path, params) => {
  const url = _getPath(path)
  const data = _getParams(params)
  //如果某个参数值为undefined,则删掉该字段,不传给后端
  for (let e in data) {
    if (data[e] === 'undefined') {
      delete data[e]
    }
  }
  // 处理请求头,加上最近比较流行的jwtToken(具体的自己百度去)
  const header = util.extend(
    true, {
    "content-type": "application/x-www-form-urlencoded",
    'Authorization': wx.getStorageSync('jwtToken') ? `Bearer ${wx.getStorageSync('jwtToken')}` : '',
  },
    header
  );
  const method = 'POST'
  return new Promise((resolve, reject) => {
    wx.request({
      url,
      method,
      data,
      header,
      success: (res) => {
        const result = _handleCode(res)
        result && resolve(res.data)
      },
      fail: function (res) {
        reject(res.data)
      }
    });
  })
}

那么如何调用呢?

//把request的 postAjax注册到getApp()下,调用时:
const app = getApp()
let postData = {
  //这里填写请求参数,基础参数里的appKey等参数可在这里覆盖传入。
}
app.postAjax(url, postData).then((res) => {
    if (res.success) {
    //这里处理请求成功逻辑。
    } else {
    //wx.showToast大家觉得麻烦也可以写到util.js里,调用时:util.toast(msg) 即可。
      wx.showToast({
        title: res.msg || '服务器错误,请稍后重试',
        icon: "none"
      })
    }
}).catch(err => {
 //这里根据自己场景看是否封装到request.js里
   console.log(err)
})

config.js 主要是处理正式环境、预发环境、测试环境、开发环境的配置

//发版须修改version, env
const env = {
  dev: {
    DOMAIN: 'https://dev-api.weixin.com'
  },
  test: {
    DOMAIN: 'https://test-api.weixin.com',
  },
  pro: {
    DOMAIN: 'https://api.qtshe.com'
  }
}
module.exports = {
  ...env.pro
}

以上就是简单的一个request的封装,包含登录态失效统一跳转、包含公共参数的统一封装。

老规矩,最后放代码片段,util里内置了md5方法以及深拷贝方法,具体的我也不啰嗦,大家自行查看即可~

https://developers.weixin.qq.com/s/gbPSLOmd7Aft
最后一次编辑于  2020-04-03  
点赞 20
收藏
评论

15 个评论

  • Youngwell
    Youngwell
    2020-04-02

    大佬请问 正式环境、预发环境、测试环境、开发环境如何切换呢?

    直接修改下面的 env.test / env.dev / env.pro,这样子吗?

    module.exports = {
      ...env.pro
    }
    
    2020-04-02
    赞同 1
    回复 12
    • TNT
      TNT
      2020-04-02
      嗯。对的。
      2020-04-02
      2
      回复
    • TNT
      TNT
      2020-04-02
      env.dev(开发环境)
      env.test(测试环境) 
      env.pre (预发环境)
      env.pro (正式环境)
      但是都得在这里配置:
      2020-04-02
      1
      回复
    • TNT
      TNT
      2020-04-02
      这是配置你本地的开发环境,并不是微信的哈。
      2020-04-02
      2
      回复
    • Youngwell
      Youngwell
      2020-04-02回复TNT
      明白了,谢谢
      2020-04-02
      回复
    • Youngwell
      Youngwell
      2020-04-02回复TNT
      准备打包上线了,就改为导出 env.pro,是吧
      2020-04-02
      回复
    查看更多(7)
  • 陈
    2020-03-13

    老规矩,先占楼

    2020-03-13
    赞同 1
    回复 1
    • TNT
      TNT
      2020-03-13
      任性
      2020-03-13
      3
      回复
  • Mr.Zhao
    Mr.Zhao
    2020-03-13

    小机灵鬼

    2020-03-13
    赞同 1
    回复 1
    • TNT
      TNT
      2020-03-13
      哈哈哈。我是看前面有个童鞋发了,赶紧复制一份
      2020-03-13
      3
      回复
  • 七髯
    七髯
    2022-07-04

    你好,超时能处理吗?

    2022-07-04
    赞同
    回复
  • 大余
    大余
    发表于移动端
    2022-04-27
    o
    2022-04-27
    赞同
    回复
  • 金
    2021-06-15

    大佬,后台php如何判断传入的数据的

    2021-06-15
    赞同
    回复
  • 雷兴
    雷兴
    2021-01-04

    大佬我把刷新token的接口替换了wx.navigateTo({}),不会再用户无感知的情况下刷新token么

    // 存储登录态失效的跳转

    const _handleCode = (res) => {

    const {statusCode} = res

    const {msg, code} = res.data

    // code为 4004 时一般表示storage里存储的token失效或者未登录

    if (statusCode === 200 && (code === 4004)) {

    wx.navigateTo({

    url: '/pages/login/login'

    })

    }

    return true

    }

    2021-01-04
    赞同
    回复 3
    • TNT
      TNT
      2021-01-04
      你这么狠吗?用户如果没有信息呢。你手动给他登录?登录后还得告知外面重新刷新下详情接口?
      2021-01-04
      回复
    • 雷兴
      雷兴
      2021-01-04回复TNT
      是的,我这边要实现用户无感知的刷新token,刷新完之后要在请求一边上一次请求token失效的的接口
      2021-01-04
      回复
    • TNT
      TNT
      2021-01-04回复雷兴
      稳。。。。。。可以做。需要在这里面调用重新登陆的接口。并且需要搞个callback告诉外面
      2021-01-04
      回复
  • 2020-09-07

    楼主,那个代码片段打不开啊

    2020-09-07
    赞同
    回复 3
    • TNT
      TNT
      2020-09-07
      本地工具打开了吗?
      2020-09-07
      回复
    • 2020-09-08回复TNT
      现在可以了 谢谢
      2020-09-08
      回复
    • TNT
      TNT
      2020-09-08回复
      👌
      2020-09-08
      回复
  • 等风来
    等风来
    2020-08-04

    大佬../util/util.js,这个里面的代码什么呀?util.extend这个方法有用到

    2020-08-04
    赞同
    回复 3
    • TNT
      TNT
      2020-08-04
      我有放到代码片段里哈。
      2020-08-04
      1
      回复
    • TNT
      TNT
      2020-08-04
      这个js文件是放公共方法的,util.extend是深拷贝
      2020-08-04
      1
      回复
    • 等风来
      等风来
      2020-08-04回复TNT
      好滴
      2020-08-04
      回复
  • now&change
    now&change
    2020-06-05

    谢谢大佬分享,萌新直接复制粘贴。

    2020-06-05
    赞同
    回复 1
    • TNT
      TNT
      2020-06-05
      额 凶残,但是需要理解下哈,有些参数是我写的默认参数。你接口如果不需要就可以删掉的。
      2020-06-05
      1
      回复

正在加载...

登录 后发表内容