EventSource 接流日志比轮询更轻量,需后端返回 text/event-stream、no-cache 响应头及 data:...\n\n 格式;前端节流渲染、scrollIntoView 滚动到底部、white-space: pre-wrap + word-break: break-word 控制样式;IE11 回退 fetch 流式读取,注意无 BOM 和换行符规范。

用 EventSource 接流日志比轮询更轻量
直接轮询 /api/logs 会压垮后端,尤其高频率日志场景。浏览器原生 EventSource 支持服务端发送事件(SSE),连接保持、自动重连、文本流解析都内置好了,只要后端按 SSE 格式输出(data: ...\n\n),前端几行就能接住滚动日志。
常见错误是后端没设对响应头:Content-Type: text/event-stream 和 Cache-Control: no-cache 缺一不可,否则 Chrome 会缓存或拒绝连接。
- 后端需逐行输出
data: {"level":"INFO","msg":"user login"}\n\n,每条日志必须以data:开头 + 双换行结尾 -
EventSource不支持自定义请求头,如需鉴权,改用fetch+ReadableStream(但兼容性差) - 日志量大时,前端要节流渲染:只追加最后 500 条,用
element.innerHTML = logs.slice(-500).join('')替代频繁appendChild
滚动到底部要用 scrollIntoView 而非 scrollTop
scrollTop = element.scrollHeight 在某些 Safari 版本里失效,且手动算高度容易被 CSS margin/padding 干扰。用 scrollIntoView 更可靠,尤其配合 { behavior: 'smooth', block: 'nearest' } 避免跳帧。
关键点是:必须等新 原始日志含时间戳、堆栈、长 URL,直接 innerHTML 渲染会挤出容器或折行错乱。CSS 必须同时控制空白符处理和断行策略。 典型错误是只设 IE11 完全不支持 注意:Safari 15.4 之前不支持 最易忽略的是服务端日志编码:UTF-8 BOM 会导致 scrollIntoView 无效果。
el.insertAdjacentHTML('beforeend', line) 之后requestAnimationFrame 延迟到下一帧执行滚动overflow: hidden,否则 scrollIntoView 会被截断日志行样式隔离靠
white-space: pre-wrap 和 word-break
white-space: pre,导致超长行撑破仪表盘;或只设 word-break: break-all,让 JSON 键名被硬切开。
white-space: pre-wrap:保留换行和空格,允许折行 加 word-break: break-word,优先在单词间断行 + flex-shrink: 0 防止被压缩IE 不支持
EventSource?用 fetch + Response.body.getReader() 回退EventSource,但部分老系统仍需兼容。此时不能简单降级为定时轮询,而要用 fetch 流式读取——前提是后端支持 HTTP chunked encoding。getReader() 的 read() 返回 Promise,得用 while 循环 + await;Chrome/Firefox 没这问题。
const reader = response.body.getReader() 获取读取器reader.read() 返回 { done, value },value 是 Uint8Array,需转字符串:new TextDecoder().decode(chunk)
\n\n 切分日志块,再解析 data: 前缀——这部分逻辑要和 SSE 解析对齐,否则格式不一致EventSource 解析失败,所有日志流输出前必须确保无 BOM,且每行末尾是 \n(不是 \r\n)。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











