基于小程序请求接口wx.request封装的类axios请求


Posted in Javascript onJuly 02, 2020

Introduction

  • wx.request 的配置、axios 的调用方式
  • 源码戳我

feature

  • 支持 wx.request 所有配置项
  • 支持 axios 调用方式
  • 支持 自定义 baseUrl
  • 支持 自定义响应状态码对应 resolve 或 reject 状态
  • 支持 对响应(resolve/reject)分别做统一的额外处理
  • 支持 转换请求数据和响应数据
  • 支持 请求缓存(内存或本地缓存),可设置缓存标记、过期时间

use

app.js @onLaunch

import axios form 'axios'
 axios.creat({
 header: {
  content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
 },
 baseUrl: 'https://api.baseurl.com',
 ...
 });

page.js

axios
 .post("/url", { id: 123 })
 .then((res) => {
 console.log(response);
 })
 .catch((err) => {
 console.log(err);
 });

API

  axios(config) - 默认get
  axios(url[, config]) - 默认get
  axios.get(url[, config])
  axios.post(url[, data[, config]])
  axios.cache(url[, data[, config]]) - 缓存请求(内存)
  axios.cache.storage(url[, data[, config]]) - 缓存请求(内存 & local storage)
  axios.creat(config) - 初始化定制配置,覆盖默认配置

config

默认配置项说明

export default {
 // 请求接口地址
 url: undefined,
 // 请求的参数
 data: {},
 // 请求的 header
 header: "application/json",
 // 超时时间,单位为毫秒
 timeout: undefined,
 // HTTP 请求方法
 method: "GET",
 // 返回的数据格式
 dataType: "json",
 // 响应的数据类型
 responseType: "text",
 // 开启 http2
 enableHttp2: false,
 // 开启 quic
 enableQuic: false,
 // 开启 cache
 enableCache: false,

 /** 以上为wx.request的可配置项,参考 https://developers.weixin.qq.com/miniprogram/dev/api/network/request/wx.request.html */
 /** 以下为wx.request没有的新增配置项 */

 // {String} baseURL` 将自动加在 `url` 前面,可以通过设置一个 `baseURL` 便于传递相对 URL
 baseUrl: "",
 // {Function} (同axios的validateStatus)定义对于给定的HTTP 响应状态码是 resolve 或 reject promise 。如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),promise 将被 resolve; 否则,promise 将被 reject
 validateStatus: undefined,
 // {Function} 请求参数包裹(类似axios的transformRequest),通过它可统一补充请求参数需要的额外信息(appInfo/pageInfo/场景值...),需return data
 transformRequest: undefined,
 // {Function} resolve状态下响应数据包裹(类似axios的transformResponse),通过它可统一处理响应数据,需return res
 transformResponse: undefined,
 // {Function} resolve状态包裹,通过它可做接口resolve状态的统一处理
 resolveWrap: undefined,
 // {Function} reject状态包裹,通过它可做接口reject状态的统一处理
 rejectWrap: undefined,
 // {Boolean} _config.useCache 是否开启缓存
 useCache: false,
 // {String} _config.cacheName 缓存唯一key值,默认使用url&data生成
 cacheName: undefined,
 // {Boolean} _config.cacheStorage 是否开启本地缓存
 cacheStorage: false,
 // {Any} _config.cacheLabel 缓存标志,请求前会对比该标志是否变化来决定是否使用缓存,可用useCache替代
 cacheLabel: undefined,
 // {Number} _config.cacheExpireTime 缓存时长,计算缓存过期时间,单位-秒
 cacheExpireTime: undefined,
};

实现

axios.js

import Axios from "./axios.class.js";

// 创建axios实例
const axiosInstance = new Axios();
// 获取基础请求axios
const { axios } = axiosInstance;
// 将实例的方法bind到基础请求axios上,达到支持请求别名的目的
axios.creat = axiosInstance.creat.bind(axiosInstance);
axios.get = axiosInstance.get.bind(axiosInstance);
axios.post = axiosInstance.post.bind(axiosInstance);
axios.cache = axiosInstance.cache.bind(axiosInstance);
axios.cache.storage = axiosInstance.storage.bind(axiosInstance);

Axios class

初始化

  • defaultConfig 默认配置,即 defaults.js
  • axios.creat 用户配置覆盖默认配置
  • 注意配置初始化后 mergeConfig 不能被污染,config 需通过参数传递
constructor(config = defaults) {
 this.defaultConfig = config;
 }
creat(_config = {}) {
 this.defaultConfig = mergeConfig(this.defaultConfig, _config);
}

请求别名

  • axios 兼容 axios(config) 或 axios(url[, config]);
  • 别名都只是 config 合并,最终都通过 axios.requst()发起请求;
axios($1 = {}, $2 = {}) {
 let config = $1;
 // 兼容axios(url[, config])方式
 if (typeof $1 === 'string') {
  config = $2;
  config.url = $1;
 }
 return this.request(config);
 }

 post(url, data = {}, _config = {}) {
 const config = {
  ..._config,
  url,
  data,
  method: 'POST',
 };
 return this.request(config);
 }

请求方法 _request

请求配置预处理

  • 实现 baseUrl
  • 实现 transformRequest(转换请求数据)
_request(_config = {}) {
 let config = mergeConfig(this.defaultConfig, _config);
 const { baseUrl, url, header, data = {}, transformRequest } = config;
 const computedConfig = {
  header: {
  'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
  ...header,
  },
  ...(baseUrl && {
  url: combineUrl(url, baseUrl),
  }),
  ...(transformRequest &&
  typeof transformRequest === 'function' && {
   data: transformRequest(data),
  }),
 };
 config = mergeConfig(config, computedConfig);
 return wxRequest(config);
 }

wx.request

发起请求、处理响应

  • 实现 validateStatus(状态码映射 resolve)
  • 实现 transformResponse(转换响应数据)
  • 实现 resolveWrap、rejectWrap(响应状态处理)
export default function wxRequest(config) {
 return new Promise((resolve, reject) => {
 wx.request({
  ...config,
  success(res) {
  const {
   resolveWrap,
   rejectWrap,
   transformResponse,
   validateStatus,
  } = config;
  if ((validateStatus && validateStatus(res)) || ifSuccess(res)) {
   const _resolve = resolveWrap ? resolveWrap(res) : res;
   return resolve(
   transformResponse ? transformResponse(_resolve) : _resolve
   );
  }
  return reject(rejectWrap ? rejectWrap(res) : res);
  },
  fail(res) {
  const { rejectWrap } = config;
  reject(rejectWrap ? rejectWrap(res) : res);
  },
 });
 });
}

请求缓存的实现

  • 默认使用内存缓存,可配置使用 localStorage
  • 封装了 Storage 与 Buffer 类,与 Map 接口一致:get/set/delete
  • 支持缓存标记&过期时间
  • 缓存唯一 key 值,默认使用 url&data 生成,无需指定
import Buffer from '../utils/cache/Buffer';
 import Storage from '../utils/cache/Storage';
 import StorageMap from '../utils/cache/StorageMap';


 /**
 * 请求缓存api,缓存于本地缓存中
 */
 storage(url, data = {}, _config = {}) {
 const config = {
  ..._config,
  url,
  data,
  method: 'POST',
  cacheStorage: true,
 };
 return this._cache(config);
 }

 /**
 * 请求缓存
 * @param {Object} _config 配置
 * @param {Boolean} _config.useCache 是否开启缓存
 * @param {String} _config.cacheName 缓存唯一key值,默认使用url&data生成
 * @param {Boolean} _config.cacheStorage 是否开启本地缓存
 * @param {Any} _config.cacheLabel 缓存标志,请求前会对比该标志是否变化来决定是否使用缓存,可用useCache替代
 * @param {Number} _config.cacheExpireTime 缓存时长,计算缓存过期时间,单位-秒
 */
 _cache(_config) {
 const {
  url = '',
  data = {},
  useCache = true,
  cacheName: _cacheName,
  cacheStorage,
  cacheLabel,
  cacheExpireTime,
 } = _config;
 const computedCacheName = _cacheName || `${url}#${JSON.stringify(data)}`;
 const cacheName = StorageMap.getCacheName(computedCacheName);

 // return buffer
 if (useCache && Buffer.has(cacheName, cacheLabel)) {
  return Buffer.get(cacheName);
 }

 // return storage
 if (useCache && cacheStorage) {
  if (Storage.has(cacheName, cacheLabel)) {
  const data = Storage.get(cacheName);
  // storage => buffer
  Buffer.set(
   cacheName,
   Promise.resolve(data),
   cacheExpireTime,
   cacheLabel
  );
  return Promise.resolve(data);
  }
 }
 const curPromise = new Promise((resolve, reject) => {
  const handleFunc = (res) => {
  // do storage
  if (useCache && cacheStorage) {
   Storage.set(cacheName, res, cacheExpireTime, cacheLabel);
  }
  return res;
  };

  this._request(_config)
  .then((res) => {
   resolve(handleFunc(res));
  })
  .catch(reject);
 });

 // do buffer
 Buffer.set(cacheName, curPromise, cacheExpireTime, cacheLabel);

 return curPromise;
 }

到此这篇关于基于小程序请求接口wx.request封装的类axios请求的文章就介绍到这了,更多相关小程序 wx.request封装类axios请求内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
DEFER怎么用?
Jul 01 Javascript
原生javascript实现图片轮播效果代码
Sep 03 Javascript
Js数组的操作push,pop,shift,unshift等方法详细介绍
Dec 28 Javascript
三种取消选中单选框radio的方法
Sep 09 Javascript
JavaScript 数组some()和filter()的用法及区别
May 20 Javascript
JavaScript中实现键值对应的字典与哈希表结构的示例
Jun 12 Javascript
Angular ng-repeat 对象和数组遍历实例
Sep 14 Javascript
js数组与字符串常用方法总结
Jan 13 Javascript
原生JS实现列表子元素顺序反转的方法分析
Jul 02 Javascript
JavaScript模板引擎应用场景及实现原理详解
Dec 14 Javascript
jQuery+ThinkPHP实现图片上传
Jul 23 jQuery
Vue解决echart在element的tab切换时显示不正确问题
Aug 03 Javascript
JS异步宏队列与微队列原理区别详解
Jul 02 #Javascript
微信小程序自定义扫码功能界面的实现代码
Jul 02 #Javascript
JS字符串和数组如何实现相互转化
Jul 02 #Javascript
Vue父子之间值传递的实例教程
Jul 02 #Javascript
JS出现404错误原理及解决方案
Jul 01 #Javascript
vue结合el-upload实现腾讯云视频上传功能
Jul 01 #Javascript
详解vue3.0 diff算法的使用(超详细)
Jul 01 #Javascript
You might like
php中将时间差转换为字符串提示的实现代码
2011/08/08 PHP
PHP include任意文件或URL介绍
2014/04/29 PHP
JSON用法之将PHP数组转JS数组,JS如何接收PHP数组
2015/10/08 PHP
php实现的pdo公共类定义与用法示例
2017/07/19 PHP
PHP通过get方法获得form表单数据方法总结
2018/09/12 PHP
PHP架构及原理知识点详解
2019/12/22 PHP
document 和 document.all 分别什么时候用
2006/06/22 Javascript
Jquery练习之表单验证实现代码
2010/12/14 Javascript
Javascript中的for in循环和hasOwnProperty结合使用
2013/06/05 Javascript
js实现图片旋转的三种方法
2014/04/10 Javascript
使用mouse事件实现简单的鼠标经过特效
2015/01/30 Javascript
谈谈JavaScript自定义回调函数
2015/10/18 Javascript
Bootstrap编写一个在当前网页弹出可关闭的对话框 非弹窗
2016/06/30 Javascript
nodeJS实现路由功能实例代码
2017/06/08 NodeJs
dropload.js插件下拉刷新和上拉加载使用详解
2017/10/20 Javascript
微信小程序使用map组件实现检索(定位位置)周边的POI功能示例
2019/01/23 Javascript
JavaScript实现美化滑块效果
2019/05/17 Javascript
jQuery实现input[type=file]多图预览上传删除等功能
2019/08/02 jQuery
node.js使用http模块创建服务器和客户端完整示例
2020/02/10 Javascript
[02:44]完美大师赛主赛事淘汰赛第二日观众采访
2017/11/24 DOTA
Python中几种导入模块的方式总结
2017/04/27 Python
使用Template格式化Python字符串的方法
2019/01/22 Python
python 实现交换两个列表元素的位置示例
2019/06/26 Python
对Django中内置的User模型实例详解
2019/08/16 Python
简单了解python中的f.b.u.r函数
2019/11/02 Python
使用卷积神经网络(CNN)做人脸识别的示例代码
2020/03/27 Python
浅析pandas随机排列与随机抽样
2021/01/22 Python
HTML5 CSS3给网站设计带来出色效果
2009/07/16 HTML / CSS
个人党性剖析材料
2014/02/03 职场文书
校长寄语大全
2014/04/09 职场文书
英语求职信范文
2014/05/23 职场文书
2014年廉洁自律承诺书
2014/05/26 职场文书
欢迎领导标语
2014/06/27 职场文书
《莫泊桑拜师》教学反思
2016/02/22 职场文书
MySQL系列之八 MySQL服务器变量
2021/07/02 MySQL
vue 自定义的组件绑定点击事件
2022/04/21 Vue.js