小程序仿axios请求封装

一、新建request.js

/*
 * 功能:小程序仿axios的请求封装
 *
 * 创建日期:2019-12-23
 * 更新日期:2020-9-6
 * 作者:GaoShiWei
 */
export default class Request {
  // 配置项
  configure = {
    baseURL: '', // 请求的服务器地址,例如:http://xxx.com
    apiURL: '', // 请求的api接口地址,例如:/api/getUser
    requestUrl: '', // 请求接口的全路径,例如:http://xxx.com/api/getUser
    header: {
      'content-type': 'application/json;charset=utf-8;'
    }, // 请求的header,默认是body传参,可以在调用方法里指定不同的header,且会覆盖掉默认相同属性的header
    method: 'GET', // 请求的类型,支持get,post,put,delete,head,options,trace,connect
    dataType: 'json', // 返回的数据格式,默认json
    responseType: 'text', // 响应的数据格式,默认text
    data: {}, // 请求传参数据
    timeout: 3 * 60 * 1000, // 请求超时时间,默认3分钟,还未实现
    requestTask: null, // 请求任务,可以手动调用http.abort()取消本次请求
  }

  // 拦截器
  interceptors = {
    request: {
      use: (configCb, errorCb) => {
        if (configCb) this.interceptors.request.success = configCb;
        if (errorCb) this.interceptors.request.error = errorCb;
      },
      success: (successCb => successCb),
      error: (errorCb => errorCb),
    },
    response: {
      use: (successCb, errorCb) => {
        if (successCb) this.interceptors.response.success = successCb;
        if (errorCb) this.interceptors.response.error = errorCb;
      },
      success: (successCb => successCb),
      error: (errorCb => errorCb),
    }
  }

  // 构造器
  constructor(props) {
    this.configure = Object.assign({}, this.configure, props);
    this.requestTask = null; // 取消请求
  }

  // 提供create方法注入参数
  static create(configure = {}) {
    return new this(configure);
  }

  // 支持以下http请求方式,如果修改请求类型,在调用时候设置header的content-type覆盖全局配置即可
  get(url, data = {}, header = {}) {
    return this.request('GET', url, data, header);
  }
  post(url, data = {}, header = {}) {
    return this.request('POST', url, data, header);
  }
  put(url, data = {}, header = {}) {
    return this.request('PUT', url, data, header);
  }
  delete(url, data = {}, header = {}) {
    return this.request('DELETE', url, data, header);
  }
  head(url, data = {}, header = {}) {
    return this.request('HEAD', url, data, header);
  }
  options(url, data = {}, header = {}) {
    return this.request('OPTIONS', url, data, header);
  }
  trace(url, data = {}, header = {}) {
    return this.request('TRACE', url, data, header);
  }
  connect(url, data = {}, header = {}) {
    return this.request('CONNECT', url, data, header);
  }
  // 判断传参的api路径中的url是否带有http或者https前缀,有则不会拼加环境变量中的baseURL,直接会请求api中的地址
  isProtocolApiUrl(url) {
    return /(http|https):\/\/([\w.]+\/?)\S*/.test(url);
  }
  // request封装
  request(method = '', url = '', data = {}, header = {}) {
    // 设置配置参数
    this.configure.method = method;
    this.configure.apiURL = url;
    this.configure.requestUrl = this.isProtocolApiUrl(url) ? url : (this.configure.baseURL + url);
    this.configure.data = data;

    // Promise请求
    return new Promise((resolve, reject) => {
      // request拦截器没有return config或者return true,则不执行请求,抛出异常
      const before = this.interceptors.request.success(this.configure);
      if (!before) {
        this.interceptors.request.error({
          errMsg: "request:fail request interceptors,must be return data!"
        });
        reject({
          errMsg: "request:fail request interceptors,must be return data!"
        });
        return;
      };

      // 合并请求拦截器和http代码调用的header,以代码里调用http的优先级最高,拦截器里相同属性的会被覆盖掉
      this.configure.header = {
        ...this.configure.header,
        ...header
      };

      // 调用小程序的wx.request()
      this.requestTask = wx.request({
        url: this.configure.requestUrl,
        data: this.configure.data,
        header: this.configure.header,
        dataType: this.configure.dataType || 'json',
        responseType: this.configure.responseType || 'text',
        method: this.configure.method,
        success: (res) => {
          // 返回成功回调
          if (res && res.statusCode == 200) {
            // 调用response拦截器,返回数据结果到promise中
            const response = this.interceptors.response.success(res);
            resolve(response);
          } else {
            // 返回失败回调
            // 调用response拦截器,返回数据结果到promise中
            const response = this.interceptors.response.error(res);
            reject(response);
          }
        },
        fail: (err) => {
          // 返回失败回调
          // 调用response拦截器,返回数据结果到promise中
          const response = this.interceptors.response.error(err);
          reject(response);
        }
      })
    })
  }

  // 取消请求
  abort() {
    if (this.requestTask) {
      this.requestTask.abort();
    }
  }
}

二、创建http.js文件

import request from 'request.js'

/* 创建request实例 */
const service = request.create({
  baseURL: env.BASE_URL, // 可以使用环境变量的服务地址
  // baseURL: 'http://localhost:8080',  // 也可以自定义服务地址
})

/* request拦截 */
service.interceptors.request.use(config => {
  // 设置请求头
  config.header['token'] = 1234;
  config.header['sessionid'] = 888;
  // 设置请求头,不设置情况下默认是body传参,而且代码http调用设置的会覆盖掉默认相同属性的header
  config.header['content-type'] = 'application/json;charset=utf-8;';

  console.log('request-config:', config); // 不想打印可以注释掉
  // 如果要执行请求前拦截,使用return false;
  return config;
}, error => {
  console.log('request-error', error)
  return Promise.reject(error);
})

/* response拦截 */
service.interceptors.response.use(response => {
  console.log('response-success:', response); // 不想打印可以注释掉
  const res = response.data;

  if (res) {
    // 这里可以做点什么,比如通过返回的code判断登录是否过期
    // 返回请求的结果
    return res;
  } else {
    return Promise.reject(new Error(res.message || 'Error'))
  }
}, error => {
  console.log('response-error:', error);
  wx.showToast({
    icon: 'none',
    title: '程序异常',
  });
  return Promise.reject(error);
})

/* 导出 */
export default service;

三、在小程序js中使用

先引入http.js

import http from 'http.js'

调用http实例中的方法,有get,post, put,delete等

  http.post('/api/user/getList', {
      name: '小明 '
    }, {
      sessionid: 666,
    }).then(res => {
      console.log('查询到的信息:', res)
      this.setData({
        list: this.data.list.concat(res.data)
      })
    }).catch(error => {
      // console.log('查询列表失败:', error);
    })

也可以用abort来终止请求

    http.post('/api/user/getList', {
      name: util.trimAll('小明 ')
    }).then(res => {

      console.log('查询列表成功:', res.data);
      this.setData({
        list: this.data.list.concat(res.data.data)
      })
    }).catch(error => {
      console.log('查询列表失败:', error);
    })
    // 可以调用http的abort方法取消本次请求
    http.abort();

 

附上小程序基础框架的目录结构图

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值