You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 02:27:30