SWR自定义fetcher配置仅首次生效后续请求被忽略问题
问题原因
这个现象的核心逻辑非常明确:你的自定义fetcher仅在首次触发请求时被传入了SWR,没有做持久化的全局/同key绑定,SWR后续发起请求时找不到自定义fetcher,就自动回退使用了内置web预设提供的默认fetcher,和你观察到的网络面板现象完全对应:
- 首次请求是组件初始化时,你在
useSWR调用里手动传入了自定义fetcher,所以能正常带上Cookie配置走跨域逻辑; - 后续请求(包括窗口聚焦重验证、网络恢复重连、轮询、其他组件调用同缓存key触发的请求)触发时,要么传入fetcher的组件已经卸载,要么对应调用位置没有传入自定义fetcher,SWR就会调用
web-preset.js内置的极简fetch实现——这个实现没有加credentials: 'include'配置,自然不会携带Cookie,直接返回401。
常见的触发场景有三类:
- 未做全局fetcher配置:仅在单个组件的
useSWR调用中传入了fetcher,没有把fetcher注册到全局SWRConfig中,SWR的自动重验证逻辑默认从全局配置拉取fetcher,拿不到就走兜底默认值。 - 参数传错:SWR v1的参数签名为
useSWR(key, fetcher, config),如果你错误把fetcher写在第三个配置对象里,或是第二个参数传了普通配置对象而非函数,首次渲染可能碰巧取到了fetcher引用,重渲染后参数解析异常就会回退到默认fetcher。 - Fetcher引用不稳定:把fetcher定义在组件内部且没有用
useCallback包裹,某次重渲染时fetcher因为作用域、条件判断等原因变成了undefined,SWR会自动用默认fetcher兜底。
修复方法
按以下步骤配置即可彻底解决:
- 将自定义fetcher移到组件作用域外定义,保证引用稳定,同时把跨域、Cookie相关的fetch配置直接整合进fetcher里,不要拆分零散配置:
const fetcher = async (url: string) => { const res = await fetch(url, { credentials: 'include', mode: 'cors' }) return handleResponse(res) }
- 在应用根组件用
SWRConfig把fetcher注册为全局默认值:
import { SWRConfig } from 'swr' function RootApp() { return ( <SWRConfig value={{ fetcher }}> {/* 你的业务路由/组件 */} </SWRConfig> ) }
- 后续所有
useSWR调用不需要再单独传入fetcher参数,直接写useSWR('/api/user/info')即可,不管是手动触发还是自动重验证的请求,都会走自定义fetcher逻辑,不会再回退到默认的无配置fetch。 - 全局搜索项目中所有同key的
useSWR调用,确保没有手动传入其他错误的fetcher覆盖全局配置即可。
配置完成后再看网络面板,所有请求的发起方都会是你写的自定义fetcher代码,Cookie会正常携带,401问题也会消失。
内容的提问来源于stack exchange,提问作者Hiro
相关产品推荐
相关产品推荐

