小程序开发(3)-之wx.request封装
#主要的封裝是wxRequest、wxRequestGet、wxRequestPost、wxRequestPromise、headers這幾個函數,由于太過贅余不進行截圖展示,可以看utils.js
#wxRequest方法
wxRequest其實跟原始的wx.request沒有太大的不同,相當于一個中間鍵,可以更靈活的配置,可維護性更高,一致請求,首先來解析一些wxRequest,以下簡介的說明下
?
獲取本地存儲的token(ssoAuthToken),如果token存在就設置header,直接請求接口,不存在就重新刷新token之后,再請求該接口
?
isLoading是用來判斷某些接口是否需要wx.showLoading(加載中),就可能我不是所有的接口都需要loading的提示,只是部分請求時長比較久的接口需要,所以我們存了一個需要loading的數組,判斷請求的接口url是否存在這個數組中,存在就顯示loading,而這個數組的數據都是從api.js里面拿出來的,如圖一所示,我們每個API都是以對象的方式存的,為什么這樣做呢,主要是想靈活點,例如我可能需要調不同的服務器的接口,那么我就可以配置多一個baseUrl的字段,調接口就傳多一個baseUrl,如果沒有傳就使用默認的服務器域名
?
always方法其實是相當于請求失敗的一個攔截器,請求失敗后做什么事情
#wxRequestPromise方法
是加入Promise的一個操作,方便我們做鏈式調用,最后執行resolve或reject方法,返回一個Promise對象,供我們使用.then
#演示不同的請求方法代碼片段
#util.wxRequest util.wxRequest({ url: api.queryServiceAreaByName.url, data: queryServiceAreaByName, method: 'POST', success: function (res) { console.log(res); } })
#util.wxRequest util.wxRequest({url: api.queryServiceAreaByName.url,data: queryServiceAreaByName,method: 'POST',success: function (res) {console.log(res);}}) #util.wxRequestPost util.wxRequestPost({url: api.getEvaluateList.url,data,}).then(res => res.data.data).then(data => {console.log('data', data);})#util.wxRequestPost util.wxRequestPost({ url: api.getEvaluateList.url, data, }) .then(res => res.data.data) .then(data => { console.log('data', data); })
#圖一
const config = require('../config/config.js'); const dayjs = require("./dayjs"); const api = require("./api.js"); const app = getApp();const loadingApi = [api.queryServiceAreaInPoint.url,api.queryConstructionInPoint.url,api.queryServiceAreaByName.url,api.queryServiceAreaWithPoint.url,api.getUserDetails.url,api.addEvaluateItem.url,api.queryServiceAreaDetailInMap.url,api.queryOrderByPhone.url ];const formatTime = date => {const year = date.getFullYear()const month = date.getMonth() + 1const day = date.getDate()const hour = date.getHours()const minute = date.getMinutes()const second = date.getSeconds()return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':') }const formatNumber = n => {n = n.toString()return n[1] ? n : '0' + n }function headers(header) {header = header || {};//小應用特殊頭header['X-Requested-isWXAPP'] = 'YES';//session_id , vmc_uid 處理var session_id = wx.getStorageSync('_SID'),vmc_uid = wx.getStorageSync('_VMC_UID');var ownshop = wx.getStorageSync('own_shop');// SIDif (session_id)header['X-WxappStorage-SID'] = session_id;if (ownshop) {header['X-REQUESTED-HEADER-VSHOPID'] = ownshop;}// UIDif (vmc_uid)header['X-WxappStorage-VMC-UID'] = vmc_uid;if (wx.getStorageSync('merchant_id')) {header['X-WxappStorage-MCH-ID'] = wx.getStorageSync('merchant_id');}if (config.RUN_ON_SAAS && wx.getExtConfig) {var ext_vars = wx.getExtConfigSync();// SAAS RUN TYPEheader['x-requested-saas-mode'] = 'APP';header['x-requested-saas-app'] = ext_vars.host_pre;header['x-requested-saas-client'] = ext_vars.client_id;header['x-requested-saas-order'] = ext_vars.order_id;}return header; }function wxRequest(params) {let ssoAuthToken = wx.getStorageSync('sso_auth_token') || null;let isLoading = loadingApi.includes(params.url);if (!params.header) {params.header = {};}// loading加載if (isLoading) {wx.showLoading({title: '加載中',})}// 如果沒有baseUrl使用config上配置的,如果有使用傳入的if (!params.baseUrl) {params.url = config.BASE_URL + params.url;} else {params.url = params.baseUrl + params.url;}headers(params.header);//content-typeparams.header['content-type'] = params.header['content-type'] ? params.header['content-type'] : 'application/json';if (ssoAuthToken) {params.header['accessToken'] = ssoAuthToken.accessToken;params.header['refreshToken'] = ssoAuthToken.refreshToken;let serviceAreaIds = ssoAuthToken.serviceAreas.map(item => item.id);if (params.data.serviceAreaIdList) {params.header['serviceAreaIds'] = params.data.serviceAreaIdList[0];} else {params.header['serviceAreaIds'] = serviceAreaIds[0];}}// 拿到接口數據后進行處理,相當于攔截器var always = function (res) {console.log('util.js:always')if (res.data && !res.data.success) {var res_redirect = res.data.redirect;if (res_redirect && res_redirect.match && res_redirect.match(/passport-login/i)) {//服務端登錄狀態丟失,重新登錄delete (app.globalData.member);return checkMember(function () {wx.showModal({title: '已刷新用戶登錄狀態',content: '請重新進入',showCancel: false,success: function (res) {wx.navigateBack();}});});}}};if (params.success) {var _tmp = params.success;params.success = null;params.success = function (res) {always(res);_tmp(res);if (isLoading) {// setTimeout(function () {wx.hideLoading();// }, 1000)}};} else {params.success = function (res) {always(res);};}// 獲取ssoAuthToken,如果ssoAuthToken里的accessToken、refreshToken過期了,刷新后再請求接口 if (ssoAuthToken) {let timestamp = dayjs(new Date()).valueOf();if (ssoAuthToken.expiresIn < timestamp) {// 這里過期的時候可能執行多次,因為一個頁面可能調了多個接口,可以做500ms的隊列if (app && app.globalData) {app.globalData.loginModal.getTokenByRefreshToken(params);}} else {wx.request(params);}} else {wx.request(params);} }// promise 封裝 wxRequest const wxRequestPromise = (method) =>(params) => new Promise((resolve, reject) => {if (!params.url) throw 'params url not found'params.method = methodparamsFn(params, 'success', resolve)paramsFn(params, 'fail', reject)console.log('params', params);wxRequest(params)})const paramsFn = (params, fnName, cb) => {const fn = params[fnName] || (() => { })params[fnName] = nullparams[fnName] = (res) => {fn(res)cb(res)} }function wxUpload(params) {if (!params.header) {params.header = {};}headers(params.header);//content-typeparams.header['content-type'] = 'multipart/form-data';wx.uploadFile(params); } const checkMemberHook = function (page_ins, page_callback_fn) {let the_member = app.globalData.member;try {page_ins.setData({'member': the_member,});} catch (e) {//TODO}typeof page_callback_fn == 'function' && page_callback_fn(the_member); }function checkMember(callback, is_retry) {var _this = this;clearTimeout(app.getMemberTimer);app.getMemberTimer = setTimeout(function () {console.log('begin getMember at ' + new Date());app.getMember(function (member) {if (member.member_id) {return checkMemberHook(_this, callback);}wxRequest({url: config.BASE_URL + '/openapi/toauth/callback/wechat_toauth_wxapppam/callback',method: 'POST',data: member,success: function (res) {if (!res.data.result || res.data.result != 'success') {console.info('oauth server callback res error:');console.info(res);wx.showModal({title: '授權失敗',content: res.data.data || '',showCancel: (!is_retry),confirmText: (!is_retry ? '重試' : '確定'),success: function (res) {if (!is_retry && res.confirm) {checkMember.apply(_this, [callback, true]);}}});} else {// app.globalData.member.member_id = res.data.data.member_id;// app.globalData.member.openid = res.data.data.openid;Object.assign(app.globalData.member, res.data.data);checkMemberHook(_this, callback);}},complete: function () {}});});}, 0); }function formatArea(area_str = '') {var match = area_str.match(/mainland:([^:]+)/);if (match) {return match[1].split('/').join('-');} }function fix_img_url(url) {if (url.match(/^http([s]*):/)) {return url;}return 'https:' + url; }//倒計時 function count_down(that, intDiff) {function cd() {var day = 0,hour = 0,minute = 0,second = 0; //時間默認值if (intDiff > 0) {day = Math.floor(intDiff / (60 * 60 * 24)).toString();hour = (Math.floor(intDiff / (60 * 60)) - (day * 24)).toString();minute = (Math.floor(intDiff / 60) - (day * 24 * 60) - (hour * 60)).toString();second = (Math.floor(intDiff) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60)).toString();}if (day <= 9)day = '0' + day;if (hour <= 9)hour = '0' + hour;if (minute <= 9)minute = '0' + minute;if (second <= 9)second = '0' + second;if (day == 0 && hour == 0 && minute == 0 && second == 0) {clearInterval(cd);}that.setData({countdown: {days: day,hours: hour,minutes: minute,seconds: second,}});intDiff -= 1;}setInterval(cd, 1000) };function scene_parse(scene) {if (scene) {try {var scene_obj = JSON.parse(decodeURIComponent(scene));} catch (e) {return false;}if (typeof scene_obj == 'object') {return scene_obj;}return false;}return false; }/*獲取當前頁帶參數的url*/ function getCurrentPageUrlWithArgs() {var pages = getCurrentPages() //獲取加載的頁面var currentPage = pages[pages.length - 1] //獲取當前頁面的對象var url = currentPage.route //當前頁面urlvar options = currentPage.options //如果要獲取url中所帶的參數可以查看options//拼接url的參數var urlWithArgs = url + '?'for (var key in options) {var value = options[key]urlWithArgs += key + '=' + value + '&'}urlWithArgs = urlWithArgs.substring(0, urlWithArgs.length - 1)return urlWithArgs }function gotoIndex() {wx.switchTab({url: "/pages/index/index"}); }function merchantShare(url) {let merchant_id;if (wx.getStorageSync('merchant_id')) {merchant_id = wx.getStorageSync('merchant_id');} else {merchant_id = 0;}if (url.indexOf("?") != -1) {url += '&merchant_id=' + merchant_id} else {url += '?merchant_id=' + merchant_id}return url; }function getQuery(url, query) {if (url.indexOf('?') < 0)return;var arr = url.split('?');var query_arr = arr[1].split('&');for (var i = 0; i < query_arr.length; i++) {let single_arr = query_arr[i].split('=');console.log('single_arr', single_arr);if (!single_arr[1]) continue;query[single_arr[0]] = single_arr[1];}return query; }function setTabBarBadge() {wxRequest({url: config.BASE_URL + '/openapi/cart/count',success: function (res) {try {if (res.data.data.quantity > 0) {wx.setTabBarBadge({index: 1,text: res.data.data.quantity.toString(),success: function () {},fail: function () {},complete: function (e) {}})} else {wx.removeTabBarBadge({index: 1,success: function () {},fail: function () {},complete: function (e) {}})}} catch (e) {console.log(e)}}}); }// 過濾顯示服務區的擁有服務圖標 function filterServiceProvidedIcon(params) {if (!params) {return []}var IconObj = {//餐飲 coffeeActivecatering: 'coffeeActive',//住宿 oilActiveaccommodation: 'oilActive',//購物 shoppingActiveshopping: 'shoppingActive',//衛生間 toiletActivetoilet: 'toiletActive',//停車場 parkparking_lot: 'park',//加油站 gasfuel_filling: 'gas',//充電樁 chargerecharge: 'charge',//加氣站 naturalGasair_entrapping: 'naturalGas',//維修 maintainmaintenance: 'maintain',//其他服務 more}var originIcon = params.split(',')var fileterIcon = originIcon.map(element => IconObj[element])return fileterIcon.filter(ele => ele) }function setHtmlSnip(keyword, text) {return '<div>' + text.replace(new RegExp(keyword, 'g'), `<span style="color: blue">${keyword}</span>`) + '</div>' }const wxRequestGet = wxRequestPromise('GET') const wxRequestPost = wxRequestPromise('POST')function getUserInfo() {return new Promise((resolve, reject) => {const wxUserInfo = wx.getStorageSync('wx_userinfo') || {}if (wxUserInfo.nickName) {resolve(wxUserInfo)} else {wx.getUserInfo({success: (result) => {wx.setStorage({data: { ...wxUserInfo, ...result.userInfo },key: 'wx_userinfo',})resolve(result.userInfo)},complete: () => resolve({}),})}}) }const buriedPoint = async (data = {}) => {const { scene } = wx.getLaunchOptionsSync()const wxUserInfo = await getUserInfo()// console.log('wxUserInfo', wxUserInfo);data = {...data,buriedPointType: data.path ? 0 : 1,type: Number(scene !== 1001),nickName: wxUserInfo.nickName || '',phoneNumber: wxUserInfo.phoneNumber || '',}console.log('buriedPoint', data);return wxRequestPost({url: api.buriedPoint.url,data,}) }const checkLogin = () => new Promise((resolve, reject) => {const app = getApp()if (app.globalData.checkLogin) {resolve()} else {const cb = app.checkLoginReadyCallbackapp.checkLoginReadyCallback = () => {typeof cb === 'function' && cb()resolve()};} })const getTime= function(value, flag) {let theTime = parseInt(value);// 秒let middle= 0;// 分let hour= 0;// 小時let result = ""if(theTime > 60) {middle= parseInt(theTime/60);theTime = parseInt(theTime%60);if(middle> 60) {hour= parseInt(middle/60);middle= parseInt(middle%60);}if(flag) {result = ""+parseInt(theTime)+"秒"}} else {result = ""+parseInt(theTime)+"秒"}if(middle > 0) {result = ""+parseInt(middle)+"分鐘"+result;}if(hour> 0) {result = ""+parseInt(hour)+"小時"+result;}return result; }function enclosureJHpay(params) {var _this = this;let userInfo = wx.getStorageSync('wx_userinfo');return wxRequestPost({url: api.enclosureJHpay.url,data: {...params,appId: config.APPID,openId: userInfo.openId}}).then(res => {let payParams = res.data.data;return new Promise((resolve, reject) => {console.log(res)wx.requestPayment({timeStamp: payParams.timeStamp,nonceStr: payParams.nonceStr,package: payParams.mypackage,signType: payParams.signType,paySign: payParams.paySign,success: function (res) {console.log(res);resolve(res);},fail: function (err) {console.log(err);reject(err)}})})}) }function getQueryString(urlStr) {let urlParams = {};let str = urlStr.substr(urlStr.indexOf("?")+1); //從第一個字符開始 因為第0個是?號 獲取所有除問號的所有符串let strs = str.split("&");for (let i = 0; i < strs.length; i++) {let sTemp = strs[i].split("=");urlParams[sTemp[0]]=(sTemp[1]);}return urlParams }module.exports = {formatTime: formatTime,headers: headers,wxRequest: wxRequest,wxUpload: wxUpload,checkMember: checkMember,formatArea: formatArea,fixImgUrl: fix_img_url,countdown: count_down,sceneParse: scene_parse,getCurrentPageUrlWithArgs: getCurrentPageUrlWithArgs,gotoIndex: gotoIndex,merchantShare: merchantShare,getQuery: getQuery,setTabBarBadge: setTabBarBadge,filterServiceProvidedIcon: filterServiceProvidedIcon,wxRequestGet,wxRequestPost,buriedPoint,checkLogin,getUserInfo,setHtmlSnip: setHtmlSnip,getTime: getTime,enclosureJHpay: enclosureJHpay,getQueryString: getQueryString }?
?
?
?
總結
以上是生活随笔為你收集整理的小程序开发(3)-之wx.request封装的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue动态点击切换css样式且子元素动态
- 下一篇: JavaScript从入门到放弃 - (