JavaScript 实现 Fetch 请求统一拦截的两种方案

作者:拾光时间:2026-10-23 13:59:24浏览:472

本文介绍在 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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

作者最新文章