Golang配置SSE:浏览器识别响应为Document而非EventStream问题求助
解决Gin实现SSE时响应被识别为Document的问题
先给你几个核心排查点和修正方案:
1. 确保正确设置SSE必需的响应头
浏览器识别EventStream的关键是响应头里的Content-Type: text/event-stream,还要搭配缓存控制和长连接头,避免浏览器缓存或断开连接。你需要在处理函数开头就设置这些头,并且禁用Gin自动推断Content-Type的逻辑:
func sseHandler(c *gin.Context) { // 强制设置SSE响应头 c.Writer.Header().Set("Content-Type", "text/event-stream") c.Writer.Header().Set("Cache-Control", "no-cache") c.Writer.Header().Set("Connection", "keep-alive") // 跨域场景需添加这个头 c.Writer.Header().Set("Access-Control-Allow-Origin", "*") // 手动写入200状态码,避免Gin自动添加其他头 c.Writer.WriteHeader(http.StatusOK) }
2. 必须手动刷新响应缓冲
Gin的响应Writer默认会缓冲输出,导致SSE数据无法实时推送到浏览器。每次发送完一条SSE消息后,一定要调用Flush():
for i := 0; ; i++ { // 严格遵循SSE格式:data: 内容\n\n fmt.Fprintf(c.Writer, "data: 第%d条消息\n\n", i) // 强制把缓冲数据发送到客户端 c.Writer.Flush() time.Sleep(1 * time.Second) }
3. 排查干扰的中间件
如果用了gin.Default(),里面的Logger或Recovery中间件可能会修改响应头或缓冲输出。可以尝试用gin.New()只加载必要的中间件,比如:
r := gin.New() // 只加必要的中间件,避免干扰SSE r.Use(gin.Recovery())
4. 验证响应头是否正确
打开浏览器开发者工具的Network标签,找到SSE请求,查看Response Headers:
- 确认
Content-Type是text/event-stream - 没有多余的
Content-Encoding(比如gzip,流式传输不能用压缩)
前端测试代码参考
用这段代码验证SSE连接是否正常:
<!DOCTYPE html> <html> <body> <div id="log"></div> <script> const es = new EventSource('http://localhost:8080/sse'); es.onmessage = (e) => { document.getElementById('log').innerHTML += `<p>${e.data}</p>`; }; es.onerror = (err) => { console.error('SSE连接失败:', err); es.close(); }; </script> </body> </html>
内容的提问来源于stack exchange,提问作者Akhmad Ali
相关产品推荐
相关产品推荐

