Vue.js + Node.js 客户端无法接收SSE消息问题求助
问题:Vue/EventSource无法接收Node.js SSE消息,浏览器访问正常
我正在开发基于Vue.js客户端和Node.js后端的前后端分离Web应用,已在Node.js中实现SSE端点/api/v2/events(需传入clientId参数)。该端点使用compression模块,浏览器访问可正常接收SSE消息,但使用EventSource或VueSSE插件的Vue客户端及Postman均无法接收消息。
Node.js后端代码
module.exports = (request: Request, response: Response) => { // create utilities class let util: RequestUtilities = new RequestUtilities(request); try { // get request parameters let clientId = util.getParameter('clientId'); // respose write head response.writeHead(status, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Content-Encoding': 'none', 'Connection': 'keep-alive', 'Access-Control-Allow-Origin': '*' }) //response.flushHeaders() // response write response.write('TEST') response.flush(); // text message setInterval(() => { //response.write('event: message\n'); response.write(`data: ${clientId}\n`); response.flush() }, 5000); // request close request.on('close', () => { response.end('OK') });
Vue客户端组件代码
<template>...</template> <script> let sseClient; export default { methods: { buttonClick() { // using EventSource let evtSrc = new EventSource(localhost/api/v2/events?clientId=test) evtSrc.onmessage = (msg) => { console.log(msg) } evtSrc.addEventListener('progress', (evt) => { console.log(evt) }) evtSrc.addEventListener('', (evt) => { console.log(evt) }) evtSrc.onerror = (err) => { console.log(err) } // using vue-sse sseClient.connect() .then(a => { console.log(a) }) .catch(e => { console.log(e) }) } }, mounted() { this.getProcessingStatusArray(); sseClient = this.$sse.create("http://localhost:3060/api/v2/events?clientId=sadf"); sseClient.on('error', (e) => { console.log(`ERROR: ${e}`) }) sseClient.on('message', (m) => { console.log(`MESSAGE: ${m}`) }) sseClient.on('', (m) => { console.log(`MESSAGE: ${m}`) }) }, } </script>
两种方式均能成功调用端点,但无法接收服务器返回的SSE消息,请问遗漏了什么配置或步骤?
解决思路与修复方案
1. 严格遵循SSE消息格式规范
SSE协议要求每条消息必须以两个连续换行符(\n\n)结尾,浏览器可能有容错机制,但EventSource、VueSSE和Postman会严格校验格式,不符合规范的消息会被忽略。
- 修复初始响应:把
response.write('TEST')改为:response.write('data: TEST\n\n'); - 修复定时发送的消息:把
response.write(data: ${clientId}\n);改为:response.write(`data: ${clientId}\n\n`);
2. 禁用SSE端点的compression压缩
虽然你设置了Content-Encoding: none,但compression模块仍可能自动压缩响应流,而EventSource默认不处理压缩的SSE数据,导致无法解析。
- 如果你使用Express框架,直接给该路由禁用compression:
// 在路由注册时跳过压缩 app.get('/api/v2/events', compression({ filter: () => false }), yourSSEHandler);
3. 修正Vue客户端EventSource的URL语法错误
代码中new EventSource(localhost/api/v2/events?clientId=test)缺少字符串引号,会导致语法错误,无法正常创建EventSource实例。
- 修复为:
let evtSrc = new EventSource('http://localhost:3060/api/v2/events?clientId=test')
4. 确保响应头正确发送
取消注释response.flushHeaders(),确保响应头在发送消息前被立即发送到客户端,避免连接处于挂起状态:
response.writeHead(status, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'Access-Control-Allow-Origin': '*' }) response.flushHeaders(); // 取消注释这行
内容的提问来源于stack exchange,提问作者SacrumDeus
相关产品推荐
相关产品推荐

