52

原创文章,作者:stark,如若转载,请注明出处:https://shudong.wang/10231.html
图片描述

给大家提供思路,可以借鉴哈,有什么问题可以留言
taro脚手架后面文章会慢慢讲解更多技巧
https://github.com/wsdo/taro-...

为什么封装

当我们开发小程序的时候,经常会用到http请求,当然官方已经提供了请求的接口,但是我们每次请求的时候,可能会加上token,每次请求都会加上,如果不封装起来,会相当的麻烦,那么又怎么封装呢?

特性

  • 暴露get方法
  • 暴露post方法
  • post自定义contentType
  • 增加配置文件
  • token定义
  • 添加判断状态,记录异常信息
  • 增加异常错误logError日志
  • 增加统一日志上报

设计

需要对外暴露接口:get post
参数:url,传输的数据,请求头
这样我们可以很方便的使用了

在/service/下新建立一个api.js

baseOptions 方法

baseOptions(params, method = 'GET') {
    let { url, data } = params
    let contentType = 'application/x-www-form-urlencoded'
    contentType = params.contentType || contentType
    const option = {
      isShowLoading: false,
      url: base + url,
      data: data,
      method: method,
      header: { 'content-type': contentType, 'token': token }, // 默认contentType ,预留token
      success(res) {

      },
      error(e) {
        logError('api', '请求接口出现问题', e)
      }
    }
    return Taro.request(option)
  },

get方法

  get(url, data = '') {
    let option = { url, data }
    return this.baseOptions(option)
  },

post 方法

增加了contentType 不同的后端框架会要求不同的请求头部
  post: function (url, data, contentType) {
    let params = { url, data, contentType }
    return this.baseOptions(params, 'POST')
  }
这样我们就可以很方便在action里面使用了
import api from '../service/api'
api.get('news/list', params)

添加判断状态

2018-09-27-11-00-39

export const HTTP_STATUS = {
  SUCCESS: 200,
  CLIENT_ERROR: 400,
  AUTHENTICATE: 401,
  FORBIDDEN: 403,
  NOT_FOUND: 404,
  SERVER_ERROR: 500,
  BAD_GATEWAY: 502,
  SERVICE_UNAVAILABLE: 503,
  GATEWAY_TIMEOUT: 504
}

配置

export const base = "https://api.github.com/repos/"

增加异常错误logError日志

export const logError = (name, action, info) => {
  if (!info) {
    info = 'empty'
  }
  try {
    let deviceInfo = wx.getSystemInfoSync() // 这替换成 taro的
    var device = JSON.stringify(deviceInfo)
  } catch (e) {
    console.error('not support getSystemInfoSync api', err.message)
  }
  let time = formatTime(new Date())
  console.error(time, name, action, info, device)
  // 如果使用了 第三方日志自动上报
  // if (typeof action !== 'object') {
  // fundebug.notify(name, action, info)
  // }
  // fundebug.notifyError(info, { name, action, device, time })
  if (typeof info === 'object') {
    info = JSON.stringify(info)
  }

配合使用

import { HTTP_STATUS } from '../const/status'
import { base } from './config'
import { logError } from '../utils'

  baseOptions(params, method = 'GET') {
    let { url, data } = params
    // let token = getApp().globalData.token
    // if (!token) login()
    console.log('params', params)
    let contentType = 'application/x-www-form-urlencoded'
    contentType = params.contentType || contentType
    const option = {
      isShowLoading: false,
      loadingText: '正在加载',
      url: base + url,
      data: data,
      method: method,
      header: { 'content-type': contentType, 'token': token },
      success(res) {
        if (res.statusCode === HTTP_STATUS.NOT_FOUND) {
          return logError('api', '请求资源不存在')
        } else if (res.statusCode === HTTP_STATUS.BAD_GATEWAY) {
          return logError('api', '服务端出现了问题')
        } else if (res.statusCode === HTTP_STATUS.FORBIDDEN) {
          return logError('api', '没有权限访问')
        } else if (res.statusCode === HTTP_STATUS.SUCCESS) {
          return res.data
        }
      },
      error(e) {
        logError('api', '请求接口出现问题', e)
      }
    }
    return Taro.request(option)
  },

最终版本

import Taro from '@tarojs/taro'
import { HTTP_STATUS } from '../const/status'
import { base } from './config'
import { logError } from '../utils'

const token = ''

export default {
  baseOptions(params, method = 'GET') {
    let { url, data } = params
    // let token = getApp().globalData.token
    // if (!token) login()
    console.log('params', params)
    let contentType = 'application/x-www-form-urlencoded'
    contentType = params.contentType || contentType
    const option = {
      isShowLoading: false,
      loadingText: '正在加载',
      url: base + url,
      data: data,
      method: method,
      header: { 'content-type': contentType, 'token': token },
      success(res) {
        if (res.statusCode === HTTP_STATUS.NOT_FOUND) {
          return logError('api', '请求资源不存在')
        } else if (res.statusCode === HTTP_STATUS.BAD_GATEWAY) {
          return logError('api', '服务端出现了问题')
        } else if (res.statusCode === HTTP_STATUS.FORBIDDEN) {
          return logError('api', '没有权限访问')
        } else if (res.statusCode === HTTP_STATUS.SUCCESS) {
          return res.data
        }
      },
      error(e) {
        logError('api', '请求接口出现问题', e)
      }
    }
    return Taro.request(option)
  },
  get(url, data = '') {
    let option = { url, data }
    return this.baseOptions(option)
  },
  post: function (url, data, contentType) {
    let params = { url, data, contentType }
    return this.baseOptions(params, 'POST')
  }
}

全部代码

如果能帮到你帮忙点个 star
https://github.com/wsdo/taro-...

项目目录

2018-09-27-11-12-54

交个朋友

clipboard.png


如果觉得我的文章对你有用,请随意赞赏

你可能感兴趣的

24 条评论
关心 · 2018-09-27

666

回复

0

666666666666

关心 · 2018-09-27
Web_Fish · 2018-09-27

666

回复

小斌哥 · 2018-09-27

老王牛批

回复

qzp199510 · 2018-09-28

为什么打包出来没有action文件夹

回复

0

为啥要有呢?

starkwang 作者 · 2018-09-28
0

打包之后me文件夹index.js会读取action文件的counter.js,但是并没有action文件夹,就报错了

qzp199510 · 2018-09-28
0

你说项目吗?可以提issue 发错误截图吧

starkwang 作者 · 2018-09-28
maskwang · 2018-11-17

有没有全局的auth中间件? auth失效,自动跳到登录

回复

billydotzhang · 2018-11-21

你这套封装 有点牛皮啊 兄dei!

回复

大麦大 · 1月24日

在baseOptions 里直接调用request发送数据,总感觉不大合适啊,名字很容易让人混淆
我个人认为baseOption就返回一个baseOptions的object,在get或者post方法中调用
wx.request(Object.assign({},baseOption,incominParams))比较容易理解,而且可定制性更高

回复

0

那样的话,每个方法里面都要写一遍wx.request,感觉不是很好

wtto00 · 3月31日
0

改个名字叫baseRequest,另外起一个方法baseOptions 专门返回option

大麦大 · 8月6日
卖女孩的小火柴 · 4月8日

为什么这个请求封装出来,返回的数据要多包装一层data

回复

夕夏温存 · 6月28日

我用这个方法在header中写入token,后台取不到,其实是没写入,这是咋回事?

回复

0

看 network 有没有发送过去

starkwang 作者 · 6月29日
0

network是有发过去的,我后台用的koa2,ctx.get('token')是空字符串,就是没有写进入。打印的ctx.request.header也没有小程序写入的token

夕夏温存 · 6月29日
0

taro的request封装是没有问题,抱歉。
是我自己搞错了,我后台在别的接口中去取header了。

夕夏温存 · 6月29日
Arthur_knight · 9月2日

这么封装之后,怎么取消,中断请求

回复

载入中...