本文介绍在 JavaScript 中实现 Fetch 请求统一拦截的两种核心方法。由于原生 Fetch 缺乏内置拦截器,文章详细讲解了如何利用 Object.defineProperty 重写 window.fetch 属性,以及基于 Vue3 原理的 Proxy 方案。通过覆盖全局 fetch 方法,开发者可以在请求发出前统一添加 Token、设置 Header,或在响应返回后统一处理状态码,从而简化前端网络请求逻辑。
拦截器的目的
拦截器的目的
拦截器(interceptors)通常用于在发起 HTTP 请求之前或之后对请求进行统一处理,例如通过每个请求携带 Token 实现登录鉴权,或统一处理 404 等响应状态。
之前的实现
之前的实现
与 Axios 不同,Fetch 原生 API 中并未提供请求返回拦截器的相关接口。此前常见的做法是参照 Ant Design Pro,编写一个统一的请求封装方法,所有网络请求均调用该方法,以此实现请求与返回的拦截。然而,这种方式要求每次发起请求时都要引入该封装方法,是否存在更优的实现方案?
常见的一道面试题
常见的一道面试题
Vue 双向绑定的原理
- Vue2 基于 Object.defineProperty
- Vue3 基于 Proxy
极简的双向绑定
极简的双向绑定
const obj = {};
Object.defineProperty(obj, 'text', {
get: function() {
console.log('get val'); 
},
set: function(newVal) {
console.log('set val:' + newVal);
document.getElementById('input').value = newVal;
document.getElementById('span').innerHTML = newVal;
}
});
const input = document.getElementById('input');
input.addEventListener('keyup', function(e){
obj.text = e.target.value;
})
从上述代码中可以看到,其核心运用了数据劫持技术。
Object.defineProperty
查阅 MDN 文档
我们可以发现 Object.defineProperty 的标准使用方法。
Object.defineProperty(obj, prop, descriptor);
描述符(descriptor)包含以下属性与方法:
value:属性的值(此处不再赘述)。
configurable:true,这是总开关。一旦设为 false,便无法再设置其 value、writable 和 configurable 属性。
enumerable:true,表示该属性是否能在 for...in 循环中遍历出来,或出现在 Object.keys 的列举结果中。
writable:true,如果设为 false,属性的值就不能被重写,即变为只读。
set():在设置属性值时会调用此方法。
get():在访问属性值时会调用此方法。
回顾我们使用 Fetch 的方式,通常是直接调用,因为 Fetch 是 window 或 global 对象下的一个属性。每次使用 Fetch 时,实际上是在访问 window 或 global 对象的属性,这对应了上述代码中的 get 方法逻辑。
拦截器的实现
拦截器的实现
const originFetch = fetch;
Object.defineProperty(window, "fetch", {
configurable: true,
enumerable: true,
// writable: true,
get() {
return (url,options) => {
return originFetch(url,{...options,...{
headers: {
'Content-Type': 'application/json;charset=UTF-8',
Accept: 'application/json',
token:localStorage.getItem('token')
//这里统一加token 实现请求拦截
},...options.headers
}}).then(checkStatus)
// checkStatus 这里可以做返回错误处理,实现返回拦截
.then(response =>response.json())
}
});
只需将上述代码粘贴到程序入口文件中即可生效。
扩展
扩展
本文基于 Object.defineProperty 进行讲解,实际上使用 Proxy 同样可以实现相同功能。
此外,在微信小程序中,request 方法挂载在 wx 对象下,同样可以通过类似方式实现拦截。
具体实现 wx.request
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。