【小程序-慕尚花坊02】网络请求封装和注意事项
网络请求封装和注意事项
- 一,网络请求封装
- 1,封装request方法
- 2,request请求封装参数
- 3,封装请求快捷方法
- 4,案例完整代码
- 5,微信网络请求注意事项
- 5.1,成功回调-404
- 5.2,失败回调-网络错误
如需转载,请附上链接https://blog.csdn.net/m0_59269218/article/details/150726050
一,网络请求封装
从本章节开始,继续完成慕尚花坊小程序的网络请求封装,进入此系列之前,先提供一下尚硅谷给的接口文档和笔记资料,以及自己的仓库地址
- 接口文档:https://s.apifox.cn/6ed6c5c4-56c4-4619-8e2a-4817aa140e30
- 笔记资料:https://www.yuque.com/bigweb/dpa5f7/dm2ygniwxksuxy6o
- 学习视频对应链接:https://www.bilibili.com/video/BV1LF4m1E7kB
- 本系列个人的gitee仓库地址:https://gitee.com/zhenghuisheng/mu-shanghua-fang
1,封装request方法
首先在util包下面定义一个request.js的文件,随后再文件中定义一个 WxRequest 类,里面定义个构造函数和一个request方法,最后对这个类进行初始化,并export导出这个实例
class WxRequest {// 定义 constructor 构造函数,用于创建和初始化类的属性和方法constructor() {}/*** @description 发起请求的方法* @param { Object} options 请求配置选项,同 wx.request 请求配置选项* @returns Promise*/request(options) {// 使用 Promise 封装异步请求return new Promise((resolve, reject) => {// 使用 wx.request 发起请求wx.request({...options,// 接口调用成功的回调函数success: (res) => {resolve(res)},// 接口调用失败的回调函数fail: (err) => {reject(err)}})})}
}
// 对 WxRequest 进行实例化
const instance = new WxRequest()// 将 WxRequest 的实例通过模块化的方式暴露出去
export default instance
在pages中新建一个test页面,test.wxml文件代码如下,只需要一个按钮触发事件即可
<view><button bindtap="handler">测试请求</button></view>
test.js文件代码如下,有两种方式执行请求,一种是使用then获取结果,一种是根据async结合await获取结果
import instance from '../../utils/request'
Page({// 点击按钮触发 handler 方法async handler() {// 第一种调用方式:通过 then 和 catch 接收返回的值// instance// .request({// url: 'https://gmall-prod.atguigu.cn/mall-api/index/findBanner',// method: 'GET'// })// .then((res) => {// console.log(res)// })// .catch((err) => {// console.log(err)// })// 第二种调用方式:通过 await 和 async 接收返回的值const res = await instance.request({url: 'https://gmall-prod.atguigu.cn/mall-api/index/findBanner',method: 'GET'})console.log(res)}
})
2,request请求封装参数
上面的请求用的是微信原生的请求,在项目中也可以将这个request进行封装,设置一些默认参数,将域名封装等操作,省去在调用时传入,只需要传具体的接口名称即可。
首先在request.js文件的WxRequest类中,封装一些默认的参数,后续将构造方法中传入的参数进行替换即可。
// 默认参数对象
defaults = {baseURL: '', // 请求基准地址url: '', // 开发者服务器接口地址data: null, // 请求参数method: 'GET', // 默认请求方法header: { // 请求头'Content-type': 'application/json' // 设置数据的交互格式},timeout: 60000 // 小程序默认超时时间是 60000,一分钟
}
随后定义构造方法函数,只要实例化了构造方法,那么就会将传入进来的参数进行合并
// 定义 constructor 构造函数,用于创建和初始化类的属性和方法
constructor(params = {}) {// 在实例化时传入的参数能够被 constructor 进行接收console.log(params)// 使用 Object.assign 合并默认参数以及传递的请求参数this.defaults = Object.assign({}, this.defaults, params)
}
随后在暴露的实例instance中,会第一次的调用构造函数,将默认参数进行替换,然后将实例暴露出去,也就是说暴露的实例的默认参数会自带这个baseUrl和timeOut两个参数
// 对 WxRequest 进行实例化,不管是这里还是外面都是用上面定义的构造方法
// 只要是对象即可,不会像java一样那么严格
const instance = new WxRequest({baseURL: 'https://gmall-prod.atguigu.cn/mall-api',timeout: 15000
})// 将 WxRequest 的实例通过模块化的方式暴露出去
export default instance
最后再request的请求中,需要再次合并一下参数,将外部传来的参数和默认参数进行合并
request(options) {// 拼接完整的请求地址options.url = this.defaults.baseURL + options.url// 合并请求参数options = {...this.defaults,...options}
}
在调用方中,传入的url只需要传入接口即可,不需要传具体的域名等
const res = await instance.request({url: '/index/findBanner',method: 'GET'
})
点击测试请求之后,依旧是可以获取到返回的响应结果,说明此次也是封装成功
3,封装请求快捷方法
为了让请求封装更加的整洁,因此将相应的请求再次进行一次封装,封装完成后只需要通过以下的样式进行接口请求即可,就能将相应返回
instance.get('请求地址', '请求参数', '请求配置')
instance.delete('请求地址', '请求参数', '请求配置')
instance.post('请求地址', '请求参数', '请求配置')
instance.put('请求地址', '请求参数', '请求配置')
接下来对上面四个请求进行封装,首先进行get请求的封装在request.js文件中的wxRequest类中,定义get请求方式,参数含义如下,url表示请求的接口,data表示query的参数,method表示请求的方法,config表示需要覆盖的默认参数,最后只需要调用内部的request请求即可。其代码如下:
//url表示请求的接口,data表示query的参数,method表示请求的方法,config表示需要覆盖的默认参数
get(url, data={}, config={}){return this.request(Object.assign({url, data, method:"GET"}), config)
}
在test.js文件中进行就可以直接调用这个get请求的方法
const res = await instance.get("/index/findBanner")
使用封装的get请求之后,通过控制台的打印可以得知,依旧是可以拿到响应数据的
接下来剩余三个封装的代码如下,依旧是在js中定义响应的代码即可,只需要对请求方式method进行替换
// 封装 POST 实例方法
post(url, data = {}, config = {}) {return this.request(Object.assign({ url, data, method: 'POST' }, config))
}
// 封装 PUT 实例方法
put(url, data = {}, config = {}) {return this.request(Object.assign({ url, data, method: 'PUT' }, config))
}
// 封装 DELETE 实例方法
delete(url, data = {}, config = {}) {return this.request(Object.assign({ url, data, method: 'DELETE' }, config))
}
4,案例完整代码
上面案例的完整代码如下,首先是这个request.js代码如下,最终完整版可以直接通过最后封装的四个快捷方式进行完了请求,后续代码只需要关注具体的业务细节,不需要再关注底层的实现
class WxRequest {//url表示请求的接口,data表示query的参数,method表示请求的方法,config表示需要覆盖的默认参数get(url, data={}, config={}){return this.request(Object.assign({url, data, method:"GET"}), config)}// 封装 POST 实例方法post(url, data = {}, config = {}) {return this.request(Object.assign({ url, data, method: 'POST' }, config))}// 封装 PUT 实例方法put(url, data = {}, config = {}) {return this.request(Object.assign({ url, data, method: 'PUT' }, config))}// 封装 DELETE 实例方法delete(url, data = {}, config = {}) {return this.request(Object.assign({ url, data, method: 'DELETE' }, config))}// 默认参数对象defaults = {baseURL: '', // 请求基准地址url: '', // 开发者服务器接口地址data: null, // 请求参数method: 'GET', // 默认请求方法header: { // 请求头'Content-type': 'application/json' // 设置数据的交互格式},timeout: 60000 // 小程序默认超时时间是 60000,一分钟}// 定义 constructor 构造函数,用于创建和初始化类的属性和方法constructor(params = {}) {// 在实例化时传入的参数能够被 constructor 进行接收console.log(params)// 使用 Object.assign 合并默认参数以及传递的请求参数this.defaults = Object.assign({}, this.defaults, params)}/*** @description 发起请求的方法* @param { Object} options 请求配置选项,同 wx.request 请求配置选项* @returns Promise*/request(options) {// 拼接完整的请求地址options.url = this.defaults.baseURL + options.url// 合并请求参数options = {...this.defaults,...options}// 使用 Promise 封装异步请求return new Promise((resolve, reject) => {// 使用 wx.request 发起请求wx.request({...options,// 接口调用成功的回调函数success: (res) => {resolve(res)},// 接口调用失败的回调函数fail: (err) => {reject(err)}})})}
}
// 对 WxRequest 进行实例化,不管是这里还是外面都是用上面定义的构造方法
// 只要是对象即可,不会像java一样那么严格
const instance = new WxRequest({baseURL: 'https://gmall-prod.atguigu.cn/mall-api',timeout: 15000
})// 将 WxRequest 的实例通过模块化的方式暴露出去
export default instance
test.js完整代码如下,包含三种调用方式,最后都可以选择最后这种方式进行实际业务开发
import instance from '../../utils/request'
Page({// 点击按钮触发 handler 方法async handler() {// 第一种调用方式:通过 then 和 catch 接收返回的值// instance// .request({// url: 'https://gmall-prod.atguigu.cn/mall-api/index/findBanner',// method: 'GET'// })// .then((res) => {// console.log(res)// })// .catch((err) => {// console.log(err)// })// 第二种调用方式:通过 await 和 async 接收返回的值// const res = await instance.request({// url: '/index/findBanner',// method: 'GET'// })const res = await instance.get("/index/findBanner",{},{})console.log(res)}
})
test.wxml文件的代码如下,就是一个简单的测试按钮
<view><button bindtap="handler">测试请求</button></view>
或者也可以直接访问仓库地址进行代码的拷贝或者获取: 代码地址
5,微信网络请求注意事项
在wx请求中,会存在一些问题,在回调函数中,存在成功回调和失败回调,但是成功回调和失败回调和一般的web返回的可能不太一样
- success成功回调:指的是只要访问到了服务器都属于成功回调,不管返回的code是200还是其他
- fail失败回调:一般指的是网络出现异常的情况,才会出现这个失败回调
Page({sendRequest() {wx.request({url: 'https://gmall-prod.atguigu.cn/mall-api/index/findCategory111',method: 'GET',timeout: 10,// timeout: 10, 测试网络超时,需要调整网络success: (res) => {console.log('只要成功接收到服务器返回,不管状态是多少,都会进入 success 回调')console.log(res)},fail: (err) => {console.log('网络出现异常,会进入 fail 回调')console.log(err)}})}
})
5.1,成功回调-404
举个例子,返回一个不存在的url,将url设置成如下,将findCategory替换成findCategory111
url: 'https://gmall-prod.atguigu.cn/mall-api/index/findCategory111',
其响应效果如下,虽然是返回了404的错误码以及错误请求,但是还是进入的是成功回调
5.2,失败回调-网络错误
接下来测试网络异常的问题,设置超时时间为10ms,然后填写正确的url
url: 'https://gmall-prod.atguigu.cn/mall-api/index/findCategory',
//测试网络超时,需要调整网络
timeout: 10,
其效果如下,进入了失败的回调,并且报错内容也是网络超时,也只有这种情况才会进入失败回调