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

Next.js项目中如何修复EventSource not defined错误

Next.js项目调用EventSource报EventSource is not defined问题

问题背景

  • 正在Next.js项目中接入SSE Events,已获取到可访问SSE事件的对应URL
  • 初始实现代码如下:
const ssEvents = new EventSource(stream_url,{withCredentials:false})
  
ssEvents.addEventListener("participant.details", (e)=>{
  var data = JSON.parse(e.data)
  console.log(data)
})
  • 运行时抛出EventSource not defined错误:编写代码时TypeScript可正常识别EventSource类型、也可正常调用.addEventListener方法,但实际执行就触发报错,不确定是否遗漏配置、是否需要引入额外依赖
  • 报错栈信息:
error - pages/index.tsx (55:19) @ Home
ReferenceError: EventSource is not defined

  54 | 
> 55 |   const ssEvents = new EventSource(stream_url,{withCredentials:false})
     |                   ^
  56 | 
  • 项目tsconfig.json配置如下:
{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    "src/utils/analytics/index.js",
    "react-google-captcha.d.ts",
    "src/providers/apollo.tsx",
    "src/providers/apollo-client.ts",
    "src/utils/wallet/walletManager.js"
  ],
  "exclude": ["node_modules"]
}

问题根因

EventSource是浏览器端专属Web API,仅存在于浏览器全局上下文,Node.js服务端环境没有该全局对象。Next.js默认会对页面做服务端渲染(SSR),当前代码在服务端渲染阶段就执行了new EventSource()逻辑,直接触发未定义错误。
tsconfig中配置了dom类型库,仅能让TypeScript在编译阶段识别浏览器API的类型,不会给服务端运行时注入对应的实现,所以写代码时不会报类型错误,但运行时会报错。

修复方案

根据使用场景选对应方案即可:

  • 客户端使用SSE场景(绝大多数情况):把EventSource初始化、事件监听的逻辑放到仅客户端执行的钩子中
    • Pages Router函数组件:将逻辑放到useEffect回调中,该回调仅会在客户端hydration完成后执行,不会在服务端运行,示例代码:
      useEffect(() => {
        const ssEvents = new EventSource(stream_url, { withCredentials: false })
        const handleParticipantDetails = (e: MessageEvent) => {
          const data = JSON.parse(e.data)
          console.log(data)
        }
        ssEvents.addEventListener("participant.details", handleParticipantDetails)
        // 组件卸载时清理监听、关闭连接,避免内存泄漏
        return () => {
          ssEvents.removeEventListener("participant.details", handleParticipantDetails)
          ssEvents.close()
        }
      }, [stream_url])
      
    • Pages Router类组件:将逻辑放到componentDidMount生命周期中执行
    • App Router场景:使用EventSource的组件需要在文件顶部添加'use client'指令标记为客户端组件,再配合useEffect存放相关逻辑
  • 服务端场景需要调用SSE:安装Node.js环境兼容的SSE客户端依赖eventsource,TypeScript项目额外安装类型包@types/eventsource,引入后使用即可,不要调用浏览器内置的EventSource。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 03:49:13