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

React.js应用中EventSource on-message处理器未触发问题排查

解决React中EventSource onmessage不触发的问题

针对你遇到的React CRA环境下SSE连接正常但onmessage不执行的问题,结合旧jQuery客户端正常的情况,可按以下步骤排查解决:

1. 修复EventSource实例的作用域与生命周期问题

你当前在组件顶层直接创建EventSource实例,组件每次渲染都会重新生成新实例,导致useEffect中绑定的事件可能关联到已失效的实例上。改用useRef保存实例,确保整个组件生命周期内只有一个有效实例:

import { useRef, useEffect } from 'react';

// ...组件内部
const eventSourceRef = useRef(null);

useEffect(() => {
  // 仅在实例不存在时创建
  if (!eventSourceRef.current) {
    eventSourceRef.current = new EventSource("/api/register/39/event/944?registrationCode=MDB");

    eventSourceRef.current.onopen = (e) => {
      console.log("DEBUG: eventSource connection open!", e);
      console.log(`DEBUG: onopen | readyState=${eventSourceRef.current.readyState}`);
    };

    eventSourceRef.current.onerror = (e) => {
      if (eventSourceRef.current.readyState === EventSource.CLOSED) {
        console.log("DEBUG: eventSource connection CLOSED! Trying to reconnect!");
      }
    };

    eventSourceRef.current.onmessage = (event) => {
      console.log("DEBUG: onmessage received! result=", event.data);
    };
  }

  // 组件卸载时关闭连接
  return () => {
    if (eventSourceRef.current) {
      eventSourceRef.current.close();
      eventSourceRef.current = null;
    }
  };
}, []); // 空依赖数组确保仅执行一次

2. 配置CRA代理以支持SSE流式响应

CRA默认代理可能未正确处理SSE的长连接与流式响应,需手动创建代理配置文件src/setupProxy.js:

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    '/api',
    createProxyMiddleware({
      target: 'https://localhost:7001',
      changeOrigin: true,
      secure: false, // 本地自签HTTPS证书时需开启
      onProxyReq: (proxyReq) => {
        // 保持长连接,避免代理自动添加Connection: close
        proxyReq.setHeader('Connection', 'keep-alive');
      },
      onProxyRes: (proxyRes) => {
        // 确保SSE响应头正确传递
        proxyRes.headers['Cache-Control'] = 'no-cache';
        proxyRes.headers['Content-Type'] = 'text/event-stream';
        // 移除可能阻塞流式响应的头
        delete proxyRes.headers['Content-Length'];
      }
    })
  );
};

修改后需重启React开发服务生效。

3. 验证后端SSE响应格式是否严格符合规范

尽管旧客户端正常,不同客户端对SSE格式的容错性有差异。检查后端返回的每条消息必须符合:

  • 以data: 开头
  • 单条消息可跨行,每行都需data: 前缀
  • 消息结尾必须是两个换行符(\n\n)

示例正确格式:

data: {"type": "notice", "content": "test"}

data: {"type": "alert", "content": "new message"}

可在浏览器Network面板中查看SSE请求的「Response」标签,确认格式是否合规。

4. 检查是否存在自定义事件类型

如果后端发送的是带event:字段的自定义事件(而非默认的message事件),onmessage不会触发,需监听对应事件名:

// 在useEffect中添加自定义事件监听
eventSourceRef.current.addEventListener('custom-event-name', (event) => {
  console.log("Custom event received:", event.data);
});

可通过后端日志或Network响应内容确认是否存在event: xxx字段。


内容的提问来源于stack exchange,提问作者jn4

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 02:57:48