React中如何拦截SSE请求?解决令牌过期重连授权更新问题
React中EventSourcePolyfill SSE令牌过期重连更新方案
问题场景
在React项目中使用EventSourcePolyfill实现SSE时,已成功在初始请求中添加Authorization令牌,但令牌过期后,SSE自动重连时无法更新令牌,且直接修改实例的headers属性无效(该属性未暴露),不想通过onerror回调递归创建新实例来解决。
解决方案:利用fetchInitCallback动态注入最新令牌
EventSourcePolyfill提供了fetchInitCallback参数,该回调会在**每次发起请求(包括初始连接和自动重连)**时被调用,可通过它动态修改请求头,注入最新的授权令牌。
步骤1:封装获取最新令牌的方法
先实现一个能获取当前有效令牌的函数,比如从本地存储、状态管理工具(Redux/Context)中读取:
// 示例:从localStorage获取最新令牌 const getLatestToken = () => { return localStorage.getItem('authToken') || ''; };
步骤2:创建EventSourcePolyfill实例时配置回调
在实例化时传入fetchInitCallback,每次请求前更新Authorization头:
import { EventSourcePolyfill } from 'event-source-polyfill'; const initSSE = () => { const es = new EventSourcePolyfill('你的SSE接口地址', { fetchInitCallback: (fetchOptions) => { // 动态覆盖/添加Authorization头 fetchOptions.headers = { ...fetchOptions.headers, 'Authorization': `Bearer ${getLatestToken()}` }; return fetchOptions; } }); // 处理消息回调 es.onmessage = (event) => { // 你的业务逻辑处理 console.log('收到SSE消息:', event.data); }; // 处理错误 es.onerror = (e) => { if (e.readyState === EventSource.CLOSED) { console.log('SSE连接已关闭'); } else { console.error('SSE连接出错:', e); } }; return es; }; // 初始化SSE const sseInstance = initSSE();
步骤3:配合令牌刷新逻辑
当后端返回令牌过期的信号(比如返回401状态码,或者通过SSE事件推送token_expired消息),先执行令牌刷新逻辑更新本地令牌,之后SSE的自动重连会触发fetchInitCallback,自动使用新令牌发起请求:
// 示例:监听令牌过期事件 es.onmessage = (event) => { if (event.data === 'token_expired') { // 调用令牌刷新接口,更新本地存储的令牌 refreshAuthToken().then(() => { // 手动关闭当前连接,触发立即重连(可选,也可等待自动重连) sseInstance.close(); // 重新初始化SSE(如果需要立即重连) sseInstance = initSSE(); }); } else { // 正常业务消息处理 console.log('收到SSE消息:', event.data); } };
核心优势
- 无需在
onerror中递归创建实例,避免内存泄漏和重复创建的问题 - 每次请求(包括重连)都会自动获取最新令牌,确保授权有效性
- 利用库内置的回调机制,逻辑更简洁可控
内容的提问来源于stack exchange,提问作者crystal_test
相关产品推荐
相关产品推荐

