5 拦截器拦截请求路由_手写简易版axios拦截器,实现微信小程序wx.request的封装与拦截...
前言: axios是一个功能强大的网络请求库,其中拦截器又是axios的精髓。在小程序的开发或者需要手动实现ajax的时候,没有实现对请求的拦截,开发的时候非常不方便,因此手写一个简易版的axios拦截器。
拦截器的实现
1、实现思路
1、实现一个通用的请求request函数,所有请求都调用这个函数去进行网络请求
2、请求调用request函数
3、在正式发送请求前,执行请求前beforeRequest拦截函数
4、拿到beforeRequest的返回值,其返回值是修改后的请求参数config
5、正式发送请求
6、在请求响应后,执行beforeResponse函数,其返回值是对response数据处理后的值
7、request正式返回,请求结束
2、简易版axios的结构
根据实现思路得出的axios的结构
class Axios {
constructor() {
// 定义拦截器对象
this.interceptors = {}
// 默认的配置文件
this.config = {}
}
// axios的初始化函数,初始化时对config进行赋值
static create(){}
// 请求发送前的拦截函数
beforeRequest() {}
// 请求响应的拦截函数
beforeResponse() {}
// 通用的request函数
async request() {}
// 真正发送请求的函数
sendRequest(config) {}
// get请求
get(){}
// post请求
post(){}
}
export default Axios
为了实现方便,我把axios声明为一个class,里面主要实现了几个关键函数:create
、 beforeRequest
、 beforeResponse
、 request
、 sendRequest
。其中请求方法大家可以根据需求加,我这里列了两个常用的, get
、 post
。
3、具体函数的实现
1、this.interceptors
this.interceptors = {
// 请求拦截
request: {
// 给函数绑定当前的this,否则this会指向request
use: this.beforeRequest.bind(this),
success: noonFunc,
fail: noonFunc
},
// 相应拦截
response: {
use: this.beforeResponse.bind(this),
success: noonFunc,
fail: noonFunc
}
}
拦截器对象,对象里面包括了两个对象, request
、 response
,其中 use
就是调用拦截器的使用函数,如
axios.interceptors.request.use()
axios.interceptors.response.use()
2、this.config
默认的配置文件
// 默认的配置文件
this.config = {
// 请求的基础路由
baseURL: 'http://127.0.0.1/',
timeout: 6000,
method: 'GET',
dataType: 'json',
responseType: 'text',
Authorization: '',
ContentType: 'application/json'
}
3、create
axios的初始化函数,对默认参数进行合并并返回一个axios实例。之所以使用静态方法,是因为使用的时候不要再new一个实例,直接调用 Axios.create
/**
* axios的初始化函数,初始化时对config进行赋值
* 当参数没有传入时,使用默认参数
* @param baseURL
* @param timeout
* @param method
* @param dataType
* @param responseType
* @param ContentType
* @param Authorization
*/
static create({
baseURL = '',
timeout = 5000,
method = 'GET',
dataType = 'json',
responseType = 'text',
ContentType = 'application/json',
Authorization = ''
} = {}) {
const axios = new Axios()
axios.config = {
baseURL,
timeout,
method,
dataType,
responseType,
ContentType,
Authorization
}
return axios
}
注: 这个axios请求里面大量使用了ES6的默认参数填充,为的是打代码时有提示,因此代码量会有一定的冗余,效果如下。
4、beforeRequest、beforeResponse
beforeRequest(successFunc = noonFunc(), failFunc = noonFunc()) {
/**
* 成功拦截函数,传入一个config
* 调用拦截的时候,会调用传入的successFunc函数
* @param config
*/
this.interceptors.request.success = (config) => {
return successFunc(config)
}
this.interceptors.request.fail = (error) => {
return failFunc(error)
}
}
beforeResponse(successFunc = noonFunc(), failFunc = noonFunc()) {
this.interceptors.response.success = (response) => {
return successFunc(response)
}
this.interceptors.response.fail = (error) => {
return failFunc(error)
}
}
拦截器自定义的实现函数,当使用 axios.interceptors.request.use()
的时候,会向该函数传入两个函数, success
和 error
,分别放到request的 success
和 error
函数里面,在请求前,就会调用 success
,得到配置参数 config
。这就是拦截器的实现思路。response的原理也类似
5、request的关键代码
return new Promise(async (resolve, reject) => {
// 请求前的拦截,一定要用await,因为拦截函数可能会有一些异步的操作
config = await this.interceptors.request.success(config)
// 如果没有返回参数,请求不再向下执行
if (!config) {
return
}
// 正式发送请求
await this.sendRequest(config).then(requestResponse => {
let response = {
statusCode: requestResponse.statusCode,
config,
data: requestResponse.data,
header: requestResponse.header,
errMsg: requestResponse.errMsg
}
// 执行成功的拦截函数,传入请求的结果
const result = this.interceptors.response.success(response)
// 有可能会返回Promise.reject,所以要判断是不是Promise
if (this._checkIsPromise(result)) {
result.catch(err => {
reject(err)
})
} else {
resolve(result)
}
}).catch(requestError => {
let error = {
error: requestError,
response: {
statusCode: requestError.statusCode,
config,
data: requestError.data,
header: requestError.header,
errMsg: requestError.errMsg
}
}
// 执行失败的拦截函数
const failResult = this.interceptors.response.fail(error)
if(this._checkIsPromise(failResult)) {
failResult.catch(err => {
reject(err)
})
}else {
reject(failResult)
}
})
})
就是在请求和响应前分别调用 interceptors
里的函数,成功调用 success
,失败时调用 error
6、sendRequest
// 真正发送请求的函数
sendRequest(config) {
return new Promise((resolve, reject) => {
uni.request({
// 如果是源请求,则不再添加baseURL
url: (this._checkIsOriginRequest(config.url) ? '' : this.config.baseURL) + config.url,
method: config.method,
data: config.data,
dataType: config.dataType,
timeout: config.timeout,
// responseType: config.responseType,
header: {
'Content-Type': config.ContentType,
'Authorization': config.Authorization
},
success: (res) => {
// 404状态码,则让它走fail回调
if(res.statusCode === 404) {
reject(res)
return
}
resolve(res)
},
fail: (err) => {
reject(err)
}
})
})
}
这里是发送请求的函数,其中 uni.request
可换成 wx.request
或其他的 ajax
请求
7、get
// get请求
get(url, data, {
timeout = this.config.timeout,
dataType = this.config.dataType,
responseType = this.config.responseType,
ContentType = this.config.ContentType,
Authorization = this.config.Authorization
} = {}) {
return this.request(url, data, {
method: 'GET',
timeout,
dataType,
responseType,
ContentType,
Authorization
})
}
其他请求也类似
8、interceptors.js
import Axios from './axios.js'
const successCode = 10000
// 初始化axios,并返回一个axios的实例
const httpInstance = Axios.create({
timeout: 6000,
baseURL: 'https://mall.cxmmao.com/api-mall',
})
// 请求前拦截,一般进行一些权限的校验,如加入token或其他请求头
httpInstance.interceptors.request.use(async config => {
// config.Authorization = 'Cxm Token'
console.log('请求发送前的数据')
console.log(config)
return config
}, error => {
console.log(error)
})
// 响应前拦截,一般进行响应数据的过来,判断是不是成功的响应
httpInstance.interceptors.response.use(response => {
const resData = response.data
console.log('请求响应前的数据')
console.log(response)
if (response.statusCode === 200) {
// 只要是成功的响应才返回响应的data,否则都是走error回调
if (resData.code === successCode) {
return resData.data
}else {
console.log(`响应状态码不为${successCode},请求出错,将被catch捕捉`)
return Promise.reject(resData)
}
}else {
if(response.statusCode === 401) {
console.log('没有权限')
}
return Promise.reject(resData)
}
return response.data
}, error => {
console.log('请求出错')
if(error.response.statusCode === 404) {
console.log('请求接口不存在')
}
return Promise.reject(error)
})
export default httpInstance
使用拦截器的代码,这里和原生的axios是一样的,其中更多逻辑可自己加入。
4、使用样例
import httpInstance from "./interceptor"
httpInstance.post('/user/login',{
email: '1532917281@qq.com',
password: '1234567'
}).then(res => {
console.log('请求响应后的数据')
console.log(res)
}).catch(err => {
console.log('catch捕捉的数据')
console.log(err)
})
使用也和原生的axios是一样的,效果截图如下。
请求成功的截图,code=10000
请求失败的截图
注: 本套代码是基于 uni-app
实现的,在微信小程序中只需将uni.request换成 wx.reques
t即可。以上就是拦截器的实现过程,如果有什么疑问或不懂的欢迎留言。
原文:https://blog.csdn.net/qq_39851888/article/details/108024074
5 拦截器拦截请求路由_手写简易版axios拦截器,实现微信小程序wx.request的封装与拦截...相关推荐
- 微信小程序服务器开小差了,微信小程序wx.request请求封装
微信小程序 wx.request RequestTask wx.request(Object object)发起 HTTPS 网络请求. 示例代码 wx.request({ url: 'test.ph ...
- 微信小程序网络请求异常怎么办_监控微信小程序wx.request请求失败
在微信小程序里,与后台服务器交互的主要接口函数是wx.request(),用于发起 HTTPS 网络请求.其重要性不言而喻.然而,却经常遇到请求失败的问题,笔者特意谷歌"wx.request ...
- 微信小程序wx.request电脑端正常,手机端失败解决方法。
开开心心在电脑端开发完微信小程序的功能,电脑端测试完全没问题,结果一上手机,无法获取内容,调试发现wx.request返回request:fail -2:net::ERR_FAILED错误. 查阅好多 ...
- 微信小程序wx.request请求服务器json数据并渲染到页面
微信小程序的数据总不能写死吧,肯定是要结合数据库来做数据更新,而小程序数据主要是json数据格式,所以我们可以利用php操作数据库,把数据以json格式数据输出即可.现在给大家讲一下,微信小程序的wx ...
- 微信小程序请求php文件报错,微信小程序wx.request请求数据报错
首先写一个后台的数据接口,地址是:http://localhost/weicms/index... 然后使用wx.request调用后台数据接口的地址 示例代码1 wx.request({ 2 url ...
- 微信小程序wx.request请求
微信小程序网络请求wx.request请求 wx.request是向指定域名发送http请求,并且需要在微信小程序管理后台中加入指定域名(微信小程序后台中只能添加https的域名,可能是微信官方觉得这 ...
- 微信小程序 wx.request异步网络请求
wx.request({url: 'https://请求的域名/', //仅为示例,并非真实的接口地址method: 'POST',data: {sessionId: sessionId},heade ...
- 微信小程序wx.request请求接口需设置header: { accept: */*,content-type: application/json },
开始使用header: { "content-type": "application/json" },发送wx.request请求,报错,后台使用 Nancy ...
- 微信小程序wx.request请求封装,和跨域的解决。
建议把所有请求抽离到不同页面对应的js文件中,可以方便后期的修改和排查问题,小程序请求是通过微信后台来请求我们的后台地址来进行后端映射.你请求的接口实际到微信的后端做了一道映射,微信后端拿到你的 wx ...
最新文章
- C# - 基于LinkLabel可动态生成多超链接信息的自定义控件
- python -m json.tool 中文乱码 Format JSON with python
- python基本使用-Python 应该怎么去练习和使用?
- C++实现一个栈(使用类模板)
- mysql环境搭载后老出错_使用Docker在window10下搭建SWOFT开发环境,mysql连接错误
- Pycharm 专业版 导入系统pip安装的包
- DIY协同办公平台(C/S)系列4之通讯录篇
- 高校表白app使用体验
- MyBatis-DynamicSQL IF判断
- 联合国再请马云出任要职
- 利用VB.NET绘制简易表白小程序
- 如何设置 Notification 中PendingIntent 的 Intent
- php和mysql防伪网站源码,2015年最新php+mysql防伪查询程序源码微信认证查询含7套模板...
- 浙江大学在Github开源了计算机课程,看完在家上个 985
- Threejs导入OBJ模型出错的一些经验之谈
- 什么是MIMO(多输入多输出),以及MIMO的分类和测试(一)
- Fortigate(飞塔)防火墙密码恢复
- 数字化时代,如何做好用户体验与应用性能管理
- 负整数的取模与取整的问题
- PMP模拟试题每日5题(5月7日)
热门文章
- linux维护光盘,SystemRescueCd--基于Gentoo的Linux光盘维护系统
- ASP怎样定义应用主题服务器,ASP.NET 4权威指南 目录
- aboboo 上一句 快捷键_锁定微信防别人偷看,苹果电脑上的微信有何不同?
- c++11仔细地将参数传递给线程std::thread
- Android开发之Retrofit常见错误@FieldMap parameters can only be used with form encoding. (parameter #1)
- A problem occurred starting process 'command 'G:\Android\sdk\ndk-bundle\toolchains\mips64el-linux-an
- android百度地图 描点,百度地图批量描点写字
- 我的世界java版记分板_我的世界计分板指令 如何使用计分板教程
- Android系统自带样式(android:theme)
- java soap 头_如何在Java中添加Soap标头