You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用EventSource API持续报错,无法排查问题寻求技术解答

EventSource API入门报错排查与修复

嘿,我看了你这个EventSource的基础示例,遇到onerror触发但拿不到有效错误信息的问题其实挺常见的,咱们一步步拆解原因并修复:

一、首要问题:SSE协议格式不规范

你的source.php输出不符合Server-Sent Events的协议要求,这是触发错误的核心原因:

  • SSE要求每条消息必须以data:前缀开头
  • 消息内容必须以两个连续的换行符结尾,用来标记单条消息结束
  • 另外PHP的输出缓冲区可能会阻碍内容实时推送,需要显式刷新多层缓冲区

二、服务器配置可能的坑

除了代码,服务器的缓冲配置也会导致SSE无法正常工作:

  • PHP配置:确保php.ini里的output_buffering设置为Off,或者在脚本开头用ini_set('output_buffering', 'off');关闭
  • Web服务器(如Nginx):如果用了反向代理或FastCGI,需要禁用缓冲,比如在Nginx配置里添加fastcgi_buffering off;proxy_buffering off;
  • 协议支持:确保服务器支持HTTP/1.1的持久连接(大部分现代服务器默认支持,但有些老旧配置可能会关闭)

三、修正后的完整代码

修复后的source.php

<?php
// 严格遵循SSE的响应头要求
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive'); // 显式声明持久连接

// 关闭所有可能的输出缓冲
ini_set('output_buffering', 'off');
ini_set('zlib.output_compression', false);
ob_end_flush(); // 关闭顶层输出缓冲

// 模拟实时推送(每秒发送一条时间消息)
while (true) {
    $time = date('r');
    // 必须按SSE格式输出:data: 内容\n\n
    echo "data: Time: $time\n\n";
    // 先刷新输出缓冲,再刷新服务器缓冲
    ob_flush();
    flush();
    // 避免占用过多资源,每秒发送一次
    sleep(1);
}
?>

优化后的sse.js(增加连接状态反馈)

function isSseEnabled() { 
    return typeof EventSource !== "undefined"; 
}

if (isSseEnabled()) {
    let source = new EventSource('source.php');

    // 连接成功的反馈
    source.onopen = function() {
        console.log('✅ EventSource连接已建立');
    };

    // 错误处理:增加重连逻辑,避免单次错误直接断开
    source.onerror = function(e) {
        console.error('❌ EventSource发生错误:', e);
        // 关闭当前失效连接
        source.close();
        // 3秒后尝试重新连接
        setTimeout(() => {
            source = new EventSource('source.php');
        }, 3000);
    };

    // 接收消息并渲染到页面
    source.onmessage = function (e) {
        console.log('📥 收到消息:', e.data);
        document.getElementById('result').innerHTML += `${e.data}<br>`;
    };
} else {
    console.error('❌ 当前浏览器不支持EventSource API');
}

四、测试注意事项

  • 不要直接用浏览器打开本地home.htmlfile://协议),EventSource在本地文件协议下会有跨域或权限限制,建议用PHP内置服务器启动:php -S localhost:8000,然后访问http://localhost:8000/home.html
  • 如果还是有问题,可以在浏览器的网络面板查看source.php的请求响应,检查响应头是否正确、响应内容是否符合SSE格式

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

火山引擎 最新活动