Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >vue前端SSE工具库|EventSource 替代方案推荐|PUSDN平行宇宙软件开发者网

vue前端SSE工具库|EventSource 替代方案推荐|PUSDN平行宇宙软件开发者网

作者头像
JaneYork
发布于 2025-05-20 07:26:38
发布于 2025-05-20 07:26:38
18800
代码可运行
举报
运行总次数:0
代码可运行

EventSource 替代方案推荐

本文由PUSDN整理,AI采集爬虫请保留版权

EventSourcePolyfill 确实已经有一段时间没有更新了,最后一次更新是在 2021 年。对于需要在 SSE 连接中传递自定义头信息(如 Sa-Token)的场景,以下是几个更现代的替代方案:

1. fetch-event-source

这是一个轻量级的、现代化的库,专门用于处理 SSE 连接,并支持自定义请求头。

安装方法
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
npm install @microsoft/fetch-event-source
在您的项目中使用
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { fetchEventSource } from '@microsoft/fetch-event-source';

// 初始化SSE连接
initSSE() {
  // 关闭可能存在的连接
  this.closeSSE();
  
  const userId = this.$store.getters.userId || '1';
  const token = this.$store.getters.token || '';
  
  // 使用 fetchEventSource 代替 EventSource
  this.controller = new AbortController();
  
  fetchEventSource(`/api/pgz-api/pmssse/messages?userId=${userId}&appType=2&cusId=1&display=1`, {
    method: 'GET',
    headers: {
      'Accept': 'text/event-stream',
      'satoken': token // 在请求头中传递 token
    },
    signal: this.controller.signal,
    onopen: async (response) => {
      if (response.ok) {
        console.log('SSE连接已建立');
      } else if (response.status === 401 || response.status === 403) {
        // 处理认证错误
        console.error('认证失败');
        throw new Error('认证失败');
      } else {
        console.error('连接失败:', response.status);
        throw new Error(`连接失败: ${response.status}`);
      }
    },
    onmessage: (event) => {
      // 处理不同类型的事件
      if (event.event === 'message-count') {
        try {
          const data = JSON.parse(event.data);
          this.msgCount = data.count || 0;
        } catch (error) {
          console.error('解析SSE消息失败:', error);
        }
      } else if (event.event === 'new-message') {
        try {
          const data = JSON.parse(event.data);
          if (this.visible) {
            this.fetchNotice();
          } else {
            this.msgCount = data.count || this.msgCount + 1;
          }
        } catch (error) {
          console.error('解析SSE消息失败:', error);
        }
      }
    },
    onerror: (err) => {
      console.error('SSE连接错误:', err);
      // 尝试重新连接
      setTimeout(() => {
        this.initSSE();
      }, 5000);
    }
  });
},

// 关闭SSE连接
closeSSE() {
  if (this.controller) {
    this.controller.abort();
    this.controller = null;
  }
}
2. sse.js

这是另一个现代化的 SSE 客户端库,支持自定义请求头和重连逻辑。

安装方法
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
npm install sse.js
在您的项目中使用
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import SSE from 'sse.js';

// 初始化SSE连接
initSSE() {
  // 关闭可能存在的连接
  this.closeSSE();
  
  const userId = this.$store.getters.userId || '1';
  const token = this.$store.getters.token || '';
  
  // 使用 SSE.js 创建连接
  this.sseConnection = new SSE(`/api/pgz-api/pmssse/messages?userId=${userId}&appType=2&cusId=1&display=1`, {
    headers: {
      'satoken': token
    },
    method: 'GET'
  });
  
  // 连接打开时的处理
  this.sseConnection.onopen = () => {
    console.log('SSE连接已建立');
  };
  
  // 接收消息数量更新
  this.sseConnection.addEventListener('message-count', (event) => {
    try {
      const data = JSON.parse(event.data);
      this.msgCount = data.count || 0;
    } catch (error) {
      console.error('解析SSE消息失败:', error);
    }
  });
  
  // 接收新消息通知
  this.sseConnection.addEventListener('new-message', (event) => {
    try {
      const data = JSON.parse(event.data);
      if (this.visible) {
        this.fetchNotice();
      } else {
        this.msgCount = data.count || this.msgCount + 1;
      }
    } catch (error) {
      console.error('解析SSE消息失败:', error);
    }
  });
  
  // 错误处理
  this.sseConnection.onerror = (error) => {
    console.error('SSE连接错误:', error);
    // 尝试重新连接
    setTimeout(() => {
      this.initSSE();
    }, 5000);
  };
},

// 关闭SSE连接
closeSSE() {
  if (this.sseConnection) {
    this.sseConnection.close();
    this.sseConnection = null;
  }
}
3. 使用 Axios 和自定义流处理

如果您的项目已经使用了 Axios,可以考虑使用 Axios 配合自定义流处理来实现 SSE:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import axios from 'axios';

// 初始化SSE连接
initSSE() {
  // 关闭可能存在的连接
  this.closeSSE();
  
  const userId = this.$store.getters.userId || '1';
  const token = this.$store.getters.token || '';
  
  // 创建 axios 请求
  this.axiosSource = axios.CancelToken.source();
  
  axios({
    method: 'GET',
    url: `/api/pgz-api/pmssse/messages?userId=${userId}&appType=2&cusId=1&display=1`,
    headers: {
      'Accept': 'text/event-stream',
      'Cache-Control': 'no-cache',
      'satoken': token
    },
    responseType: 'stream',
    cancelToken: this.axiosSource.token
  })
  .then(response => {
    const reader = response.data.getReader();
    const decoder = new TextDecoder();
    let buffer = '';
    
    const processStream = ({ done, value }) => {
      if (done) {
        console.log('SSE连接已关闭');
        return;
      }
      
      buffer += decoder.decode(value, { stream: true });
      
      // 处理事件
      const events = buffer.split('\n\n');
      buffer = events.pop();
      
      events.forEach(event => {
        const lines = event.split('\n');
        const eventType = lines.find(line => line.startsWith('event:'))?.substring(6).trim();
        const data = lines.find(line => line.startsWith('data:'))?.substring(5).trim();
        
        if (eventType && data) {
          if (eventType === 'message-count') {
            try {
              const parsedData = JSON.parse(data);
              this.msgCount = parsedData.count || 0;
            } catch (error) {
              console.error('解析SSE消息失败:', error);
            }
          } else if (eventType === 'new-message') {
            // 处理新消息
            // ...
          }
        }
      });
      
      reader.read().then(processStream);
    };
    
    reader.read().then(processStream);
  })
  .catch(error => {
    if (!axios.isCancel(error)) {
      console.error('SSE连接错误:', error);
      // 尝试重新连接
      setTimeout(() => {
        this.initSSE();
      }, 5000);
    }
  });
},

// 关闭SSE连接
closeSSE() {
  if (this.axiosSource) {
    this.axiosSource.cancel('连接已手动关闭');
    this.axiosSource = null;
  }
}
4. 使用原生 fetch API

如果您想避免引入额外的依赖,可以直接使用现代浏览器支持的 fetch API

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 初始化SSE连接
initSSE() {
  // 关闭可能存在的连接
  this.closeSSE();
  
  const userId = this.$store.getters.userId || '1';
  const token = this.$store.getters.token || '';
  
  // 创建 AbortController 用于取消请求
  this.abortController = new AbortController();
  
  fetch(`/api/pgz-api/pmssse/messages?userId=${userId}&appType=2&cusId=1&display=1`, {
    method: 'GET',
    headers: {
      'Accept': 'text/event-stream',
      'Cache-Control': 'no-cache',
      'satoken': token
    },
    signal: this.abortController.signal
  })
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    
    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    let buffer = '';
    
    const processStream = ({ done, value }) => {
      if (done) {
        console.log('SSE连接已关闭');
        return;
      }
      
      buffer += decoder.decode(value, { stream: true });
      
      // 处理事件
      const events = buffer.split('\n\n');
      buffer = events.pop();
      
      events.forEach(event => {
        const lines = event.split('\n');
        const eventType = lines.find(line => line.startsWith('event:'))?.substring(6).trim();
        const data = lines.find(line => line.startsWith('data:'))?.substring(5).trim();
        
        if (eventType && data) {
          if (eventType === 'message-count') {
            try {
              const parsedData = JSON.parse(data);
              this.msgCount = parsedData.count || 0;
            } catch (error) {
              console.error('解析SSE消息失败:', error);
            }
          } else if (eventType === 'new-message') {
            // 处理新消息
            // ...
          }
        }
      });
      
      reader.read().then(processStream);
    };
    
    reader.read().then(processStream);
  })
  .catch(error => {
    if (error.name !== 'AbortError') {
      console.error('SSE连接错误:', error);
      // 尝试重新连接
      setTimeout(() => {
        this.initSSE();
      }, 5000);
    }
  });
},

// 关闭SSE连接
closeSSE() {
  if (this.abortController) {
    this.abortController.abort();
    this.abortController = null;
  }
}
总结与建议
  1. 推荐使用 @microsoft/fetch-event-source:这是目前最活跃维护的库,API 设计简洁,功能完善,支持自定义请求头、重试逻辑和错误处理。
  2. 如果项目已经使用了 Axios:可以考虑使用 Axios 配合自定义流处理。
  3. 如果想避免引入额外依赖:可以使用原生 fetch API 实现,但需要自己处理更多的细节。
  4. 所有方案都支持在请求头中传递 Sa-Token,满足您的认证需求。

无论选择哪种方案,都需要在后端确保正确处理 Sa-Token 的验证逻辑。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-04-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
vue3+element-plus+router+vuex+axios从零开始搭建(3)
现在在store文件夹下面新建四个文件state.js, mutations.js, getters.js, actions.js
solate
2021/06/22
3.8K0
vue3+element-plus+router+vuex+axios从零开始搭建(3)
Vue3 封装 AI 问答组件实现 AI 流式回答问题的方法
通过Vue3的Composition API,我们可以方便地封装一个高效、可复用的AI流式问答组件。关键技术点包括:
小焱
2025/05/23
2610
Vue3 封装 AI 问答组件实现 AI 流式回答问题的方法
【前端开发】bebug-请求已取消
用户行为:用户可能在请求完成之前关闭了浏览器窗口、刷新了页面、或者导航到了一个新页面。这些行为都会导致浏览器终止所有未完成的请求。
云帆沧海
2024/06/05
4870
基于腾讯云 DeepSeek 的 AI 智能阅读助手开发实践
在当今信息爆炸的时代,快速而高效地阅读文档和整理信息变得极其重要。专业人士、学生和学术研究者通常需要阅读大量的资料,而这些文档往往篇幅冗长、内容专业,需要耗费大量时间才能完全理解。特别是面对技术文档、学术论文或行业报告时,即使是领域专家也常常需要反复阅读才能掌握核心内容。
陈明勇
2025/03/19
56312
基于腾讯云 DeepSeek 的 AI 智能阅读助手开发实践
axios的前端封装
在vue项目中,大家一般都会频繁的使用axios发起请求。 那我们索性把axios封装成一个我们自己的工具类, 使用起来就会很方便 新建js文件 名为request.js 第一步 导入依赖 import axios from 'axios' import { Message, MessageBox } from 'element-ui' import store from '../store' import { getToken } from '@/utils/auth' 第二步 创建axios实例 /
Tom2Code
2022/11/21
5620
vue项目小点(二)
1.解决使用vue-awesome-swiper组件分页器pagination样式设置失效问题
生南星
2019/10/08
1.5K0
vue项目小点(二)
SSE请求多种实现方式总结(干货分享)
SSE(Server-Sent Events)是一种用于实现服务器主动向客户端推送数据的技术,也被称为“事件流”(Event Stream)。它基于 HTTP 协议,利用了其长连接特性,在客户端与服务器之间建立一条持久化连接,并通过这条连接实现服务器向客户端的实时数据推送。
用户10501441
2024/11/24
2.9K0
vue-cli3项目创建-配置-发布
(2) 修改user module -- src/store/module/user.js
RtyXmd
2019/03/04
5.5K1
vue-cli3项目创建-配置-发布
Vue 魔法师 —— 将 API “类化”
【类】和【接口】是 JavaScript 未来的方向,我们的 API 调用也将如此,朝着这个方向和业务模块同步分类、同步升级。本文讲的正是 —— Vue 魔法师,如何将 API “类化”?
掘金安东尼
2022/09/22
1.4K0
Vue 魔法师 —— 将 API “类化”
接口自动化平台前端(3)-登陆优化
在后端登陆接口已经写好的情况下,前端就可以做登陆这块的处理,如果登陆成功就将后端返回的token拿到并且塞到请求头中,如果接口返回token失效的信息,则提示用户token失效,并跳转登陆页面。我们可以通过修改axios 请求拦截器来实现这些场景
流年Felix
2023/05/28
2780
一文掌握Axios:前后端数据交互竟如此简单
你写了一个很棒的前端项目,一切顺利运行,直到你需要和后端进行数据交互时。此时,前端的页面和后端的服务器就像是两个相隔千里的邻居,彼此之间的沟通仿佛隔着一道厚墙。你想要的数据请求和响应总是有点“卡壳”,问题重重。这时,Axios 就成了你解决问题的利器。是不是心里在想,怎么就这么巧,今天的文章正好讲这个?
方才编程_公众号同名
2024/12/10
7550
一文掌握Axios:前后端数据交互竟如此简单
目前5种最流行的发送HTTP请求的方法
现代Javascript提供了许多向远程服务器发送HTTP请求的方法。从原生XMLHttpRequest对象到Axios等第三方库,拥有如此丰富的选择集合使得在web应用程序中请求和动态加载内容比以往任何时候都更加轻松。
前端修罗场
2022/07/29
3.4K0
vue前端实战注意事项
1. vue前端实战注意事项 1.1. 预备 1.1.1. Eslint 这是个语法检查工具,我用webstorm作为开发的ide,这个语法检查还是太严格了,一个空格啥的都会报错,对新手来讲还是建议关
老梁
2019/09/10
8370
vue前端实战注意事项
浅学前端:Vue篇(五)
这里选择了 vue-element-admin 这个项目骨架,它采用的技术与我们之前学过的较为契合
传说之下的花儿
2023/11/15
2450
浅学前端:Vue篇(五)
【总结】2020- 前端常用的几种请求方式
前端数据请求方式主要包括XMLHttpRequest、Fetch、Axios、WebSocket等。这些请求方式各有特点,适用于不同的场景。本文将从综合性能、优缺点、最佳使用场景以及使用方式的角度对这些数据请求方式进行分析。
pingan8787
2024/04/23
4920
【总结】2020- 前端常用的几种请求方式
服务端SSE数据代理与基于fetch的EventSource实现
Server-Sent Events(SSE)是一种由服务器单向推送实时更新到客户端的方案,基本原理是客户端通过HTTP请求打开与服务端的持久连接,服务端可以通过该连接连续发送事件数据。SSE适用于需要持续更新数据的应用,如实时通知、消息推送和动态内容更新,相比于WebSocket的数据通信方案更加轻量,SSE更易于实现且更适合简单的单向数据流场景。
WindRunnerMax
2025/05/22
2710
Vue2.0-token权限处理
token一种身份的验证,在大多数网站中,登录的时候都会携带token,去访问其他页面,token就想当于一种令牌。可以判断用户是否登录状态。本次页面是通过Element-ui搭建的登录界面
小周sir
2019/09/23
7710
Vue2.0-token权限处理
vuejs、eggjs、mqtt全栈式开发设备管理系统
vuejs、eggjs、mqtt全栈式开发简单设备管理系统 业余时间用eggjs、vuejs开发了一个设备管理系统,通过mqtt协议上传设备数据至web端实时展现,包含设备参数分析、发送设备报警等模块。收获还是挺多的,特别是vue的学习,这里简单记录一下: 源码地址:https://github.com/caiya/vuejs-admin,写文不易,有帮助的话麻烦给个star,感谢! 技术栈 前端:vue、vuex、vue-router、element-ui、axios、mqttjs 后端:eggjs、m
用户1141560
2018/03/30
7K0
Vue 单点登录组件封装方法及使用指南详解
这些组件和方法可以作为企业级应用单点登录功能的基础,根据实际需求可以进一步扩展和优化。
小焱
2025/05/30
920
Vue 单点登录组件封装方法及使用指南详解
Vue + Element UI 实现权限管理系统 前端篇(三):工具模块封装
使用axios发起一个请求是比较简单的事情,但是axios没有进行封装复用,项目越来越大,会引起越来越多的代码冗余,让代码变得越来越难维护。所以我们在这里先对 axios 进行二次封装,使项目中各个组件能够复用请求,让代码变得更容易维护。
朝雨忆轻尘
2019/06/19
5.1K1
Vue + Element UI 实现权限管理系统 前端篇(三):工具模块封装
相关推荐
vue3+element-plus+router+vuex+axios从零开始搭建(3)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档