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

Introduction

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 请求的更多相关文章

  1. 【微信小程序】调用wx.request接口需要注意的问题

    写在前面 之前写了一篇<微信小程序实现各种特效实例>,上次的小程序的项目我负责大部分前端后台接口的对接,然后学长帮我改了一些问题.总的来说,收获了不少吧! 现在项目已经完成,还是要陆陆续续 ...

  2. 【小程序】调用wx.request接口时需要注意的问题

    写在前面 之前写了一篇<微信小程序实现各种特效实例>,上次的小程序的项目我负责大部分前端后台接口的对接,然后学长帮我改了一些问题.总的来说,收获了不少吧! 现在项目已经完成,还是要陆陆续续 ...

  3. 微信小程序:使用wx.request()请求后台接收不到参数

    问题描述: 微信小程序:wx.request()请求后台接收不到参数,我通过wx.request()使用POST方式调用请求,参数传递不到后台 解决方案: Content-Type': 'applic ...

  4. 微信小程序开发 [05] wx.request发送请求和妹纸图

    1.wx.request 微信小程序中用于发起网络请求的API就是wx.request了,具体的参数太多,此处就不再一一详举了,基本使用示例如下: wx.request({ url: 'test.ph ...

  5. 小程序不支持wx.request同步请求解决方法

    小程序为了用户体验,所有的request均为异步请求,不会阻塞程序运行 百牛信息技术bainiu.ltd整理发布于博客园 所以当你需要同步请求,锁死操作时,最好将所有的逻辑写在success:func ...

  6. 关于微信小程序遇到的wx.request({})问题

    域名请求错误问题 当我们在编写小程序,要发送请求时,wx.request({})时或许会遇到如下的问题: 一:这是因为微信小程序的开发中,域名只能是https方式请求,所以我们必须在小程序微信公众平台 ...

  7. 微信小程序--后台交互/wx.request({})方法/渲染页面方法 解析

    小程序的后台获取数据方式get/post具体函数格式如下:wx.request({}) data: { logs:[] }, onLoad:function(){ this.getdata(); } ...

  8. 一,前端---关于微信小程序遇到的wx.request({})问题

    域名请求错误问题 当我们在编写小程序,要发送请求时,wx.request({})时或许会遇到如下的问题: 一:这是因为微信小程序的开发中,域名只能是https方式请求,所以我们必须在小程序微信公众平台 ...

  9. 微信小程序 在使用wx.request时显示加载中

    微信小程序中,向后台请求数据是,通常想给用户提示正在加载中,如下图: 我们可以用wx.showLoading(OBJECT),当请求服务器的地方多了,怎么才能不每次都要去调用函数,我们只要对wx.re ...

随机推荐

  1. Java实现 LeetCode 768 最多能完成排序的块 II(左右便利)

    768. 最多能完成排序的块 II 这个问题和"最多能完成排序的块"相似,但给定数组中的元素可以重复,输入数组最大长度为2000,其中的元素最大为10**8. arr是一个可能包含 ...

  2. Java实现 蓝桥杯VIP 算法提高 研究兔子的土豪

    试题 算法提高 研究兔子的土豪 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 某天,HWD老师开始研究兔子,因为他是个土豪 ,所以他居然一下子买了一个可以容纳10^18代兔子的巨大 ...

  3. Java实现 蓝桥杯VIP 算法训练 递归求二进制表示位数

    问题描述 给定一个十进制整数,返回其对应的二进制数的位数.例如,输入十进制数9,其对应的二进制数是1001,因此位数是4. 样例输入 一个满足题目要求的输入范例. 9 样例输出 与上面的样例输入对应的 ...

  4. Java实现 蓝桥杯VIP 算法提高 质因数2

    算法提高 质因数2 时间限制:1.0s 内存限制:256.0MB 将一个正整数N(1<N<32768)分解质因数,把质因数按从小到大的顺序输出.最后输出质因数的个数. 输入格式 一行,一个 ...

  5. 第七届蓝桥杯JavaB组国(决)赛部分真题

    解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.愤怒小鸟 题目描述 X星球愤怒的小鸟喜欢撞火车! 一根平直的铁轨上两火车间相距 1000 米 两火车 (不妨称A和B) 以时速 10米 ...

  6. 三分钟搭建websocket实时在线聊天,项目经理也不敢这么写

    我们先看一下下面这张图: 可以看到这是一个简易的聊天室,两个窗口的消息是实时发送与接收的,这个主要就是用我们今天要讲的websocket实现的. websocket是什么? websocket是一种网 ...

  7. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(四)

    系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...

  8. Android官方新推的DI库 Hilt

    Android官方新推的DI库 Hilt Hilt是Google Android官方新推荐的依赖注入工具. 已加入到官方文档: Dependency injection with Hilt. 目前是a ...

  9. Nice Jquery Validator 内置属性

    required - 必填 适用于 input.textarea.select 输入框.(checkbox 与 radio 请使用 checked 规则)字段必填,则值不能为空.字段非必填,则值为空的 ...

  10. logrotate 如何执行日志按照大小切分

    说在最先的话,logrotate要设置按照文件大小来配置日志切分,需要通过三个东西. 1.配置logrotate 的配置文件 命名未任意文件,在启动的时候指定,例如/etc/weblog.conf 参 ...