实现封装之前,先看下小程序的默认请求方式
示例代码
wx.request({
url: 'test.php', //仅为示例,并非真实的接口地址
data: {
x: '',
y: ''
},
header: {
'content-type': 'application/json' // 默认值
},
success (res) {
console.log(res.data)
}
})
其实这个请求已经很方便了,但是我们还是不能满足我们的需求。比如对接口返回400等状态的统一处理,公共参数的统一封装等,话不多说,直接开始封装。
封装
建立一个request.js文件
const CONFIG = require('../config.js')
const URL = CONFIG.url
// 封装接口公共参数
const _getParams = (data = {}) => {
const timestamp = Date.now() //时间戳
const deviceId = Math.random() //随机数
const version = data.version || config.version //当前版本号,自定或者取小程序的都行
const appKey = data.appKey || config.appKey //某个小程序或者客户端的字段区分
//加密下,防止其他人随意刷接口,加密目前采用的md5,后端进行校验,这段里面的参数你们自定,别让其他人知道就行,我这里就是举个例子
const sign = data.sign || util.md5(config.appKey + timestamp + deviceId)
return Object.assign({}, {
timestamp,
sign,
deviceId,
version,
appKey
}, data)
}
/**
* get 请求, post 请求
* @param {String} url 请求url,必须
* @param {String} method 请求方式, 默认POST
* @param {Object} data 请求参数,可选
* @param {Object} option 可选配置
*
* option = {
* isSpec:'',//可选 是否为跨域请求
* specUrl:'',//可选 域名地址
* textType:'',//可选 请求参数类型,值为Boolean textType ? 'text/plain' : 'application/json'
* token:'',//可选 是否在请求头加上token信息
* }
*
*/
const request = (url, method, data, option) => {
let {isSpec = null,
specUrl = null,
textType = null,
token = null
} = option ? option :{}
let _url = isSpec ? (specUrl + url) : (URL + url)
let contentType = textType ? 'text/plain' : 'application/json'
// 处理请求头,加上最近比较流行的jwtToken
let header = token && wx.getStorageSync("accessToken") ? {
'content-type': contentType,
'Authorization': `bearer ${wx.getStorageSync("accessToken")}`
} : {
'content-type': contentType
}
data = _getParams(data|| null)
return new Promise((resolve, reject) => {
wx.request({
url: _url,
method: method || 'POST',
header: header,
data: data || '',
success(request) {
resolve(request.data)
},
fail(error) {
console.log(error)
reject(error)
},
complete(res) {
//可以将500,404状态也封装一下,但是这款我们业务需求不强烈,所以就不在意封装
if (res.statusCode === 401) { //跳转登录页
function getCurrentPageUrlWithArgs() { //获取当前页面路径及参数
const pages = getCurrentPages()
const currentPage = pages[pages.length - 1]
const url = currentPage.route
const options = currentPage.options
let urlWithArgs = `/${url}?`
for (let key in options) {
const value = options[key]
urlWithArgs += `${key}=${value}&`
}
urlWithArgs = urlWithArgs.substring(0, urlWithArgs.length - 1)
return urlWithArgs
}
wx.navigateTo({
url: `/pages/login/index?backUrl=${getCurrentPageUrlWithArgs()}`
})
}
}
})
})
}
module.exports = { request }
调用
1.页面直接调用
2.在app.js注册,页面直接调用
3.新建一个js文件,在新js文件里面调用(推荐,统一处理,便于后期维护)
新建api.js文件
const {request} = require('../reqest.js')
const {ffpUrl} = require('../config.js')
module.exports = {
//登陆
login: (params) => {
return request('/api/login', 'post', params)
}
}
需要使用接口的页面pages/index/index.js
const API = require('../api.js')
Page({
clickLogin:(){
let params = {}//参数
API.login(params).then((res) => {
//do somthing
}).catch((error)=>{
//do somthing
})
}
})
config.js
config.js主要是处理环境配置的问题,小程序不像vue打包后直接切到正式环境,所以我们每次打包上线前,都要把环境改写为线上的环境,疏忽了就会把开发环境发布到线上去
//生产环境变量配置
const mpEnv = 'dev'
const env = {
dev:'https://dev-api.weixin.com',
test: 'https://test-api.weixin.com',
pro: 'https://api.qtshe.com'
}
module.exports = {
url: env[mpEnv]
}
以上,封装完成。包含了特殊状态统一处理(登录失效跳转),公告参数封装。
其实之前写过一篇小程序的封装,但是看起来略显简单,所以就另外写了一篇(没在上一篇上改是因为那代表的是当时的自己的水平和见识,应当保留下来,以证自己的进步)
备注: