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.request即可。以上就是攔截器的實現過程,如果有什么疑問或不懂的歡迎留言。
原文:https://blog.csdn.net/qq_39851888/article/details/108024074
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的5 拦截器拦截请求路由_手写简易版axios拦截器,实现微信小程序wx.request的封装与拦截...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python列表中数据类型可以不同吗_P
- 下一篇: mysql搜索_mysql 几种搜索引擎