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

如何通过SSE捕获网络断开并阻止浏览器显示错误页面?

问题:SSE连接断开时浏览器自动跳转错误页面

我正在使用Server-Sent-Events(SSE),发现网络连接断开时浏览器总会跳转到错误页面,先是显示“This site can't be reached”,随后显示“No Internet - ERR_INTERNET_DISCONNECTED”。我确定问题出在SSE连接上,因为服务器上其他未使用SSE的站点在网络断开后仍能正常显示。

我尝试用JavaScript捕获断开事件:

sse_source.onerror = function(e) 
{
    e.preventDefault(); // prevent default, not working

    if (sse_source.readyState == EventSource.CLOSED)
    {
        // close SSE source
        sse_source.close();
    }

    // alert shows up and interrupts, but after clicking OK 
    // the browser error page is displayed
    alert('Connection to Server lost. No Live Updates.');
}

但这毫无作用。我还尝试了:

window.addEventListener('offline', updateOnlineStatus);

function updateOnlineStatus(e)
{
    e.preventDefault(); // prevent default, not working

    sse_source.close();

    alert('Connection to Server lost. No Live Updates.');
}

这里alert并未弹出,浏览器始终会显示错误页面。是否有其他JavaScript方法能让网站保持显示?

更新:
我在控制台中看到,连接断开时sse_source.onerror会完整执行,但无法阻止错误页面弹出。sse_source.onerror执行后,window.addEventListener('offline', updateOnlineStatus)也会执行,但同样无法阻止错误页面。另外,当我移除sse_source.readyState == EventSource.CLOSED判断后,sse_source.onerror中的alert能正常弹出,当时readyState的值为0。


解决方案

核心原因

浏览器跳转错误页是因为SSE连接持续失败未被正确处理,被判定为页面级加载失败。以下是具体解决步骤:

1. 重构SSE连接的错误处理与重连逻辑

放弃无效的e.preventDefault(),主动关闭失效连接并发起重连,避免浏览器持续重试触发错误页:

let sseSource;
const reconnectDelay = 3000; // 3秒后重连

function initSSE() {
    sseSource = new EventSource('/your-sse-endpoint');

    sseSource.onmessage = (e) => {
        // 处理收到的SSE消息
        console.log('Received:', e.data);
    };

    sseSource.onerror = () => {
        // 立即关闭当前失效连接
        sseSource.close();
        // 显示页面内提示(替代alert)
        const alertEl = document.getElementById('connection-alert');
        alertEl.style.display = 'block';
        alertEl.textContent = '连接已断开,正在尝试重连...';
        // 定时发起重连
        setTimeout(initSSE, reconnectDelay);
    };

    sseSource.onopen = () => {
        // 重连成功后隐藏提示
        document.getElementById('connection-alert').style.display = 'none';
    };
}

// 页面加载完成后初始化SSE
window.addEventListener('load', initSSE);

2. 用页面内提示替代alert

alert会阻塞线程,导致浏览器在弹窗关闭后继续处理错误逻辑。提前在页面中添加提示元素:

<div id="connection-alert" style="position: fixed; top: 0; left: 0; width: 100%; background: #ff4444; color: #fff; padding: 12px; text-align: center; display: none; z-index: 9999;"></div>

3. 结合网络状态事件优化连接管理

配合online/offline事件,在网络状态切换时主动管理SSE连接:

window.addEventListener('offline', () => {
    if (sseSource && sseSource.readyState !== EventSource.CLOSED) {
        sseSource.close();
        document.getElementById('connection-alert').textContent = '网络已断开,请检查网络连接';
    }
});

window.addEventListener('online', () => {
    if (!sseSource || sseSource.readyState === EventSource.CLOSED) {
        initSSE();
        document.getElementById('connection-alert').textContent = '网络已恢复,正在重新连接';
    }
});

关键注意事项

  • 不要用e.preventDefault()处理SSE错误:该事件没有可阻止的默认浏览器行为,调用无效。
  • 放弃EventSource.CLOSED判断:网络断开时readyState通常为0(CONNECTING),原判断会跳过关闭连接的逻辑,导致浏览器持续重试。
  • 确保服务器返回正确响应头:必须包含Content-Type: text/event-stream和Cache-Control: no-cache,避免缓存引发的错误判定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 05:13:16