如何在Go中向浏览器HTTP流多次写入并让内容即时生效?
实现HTTP响应的分块即时输出与执行
我需要开发一款HTTP调试工具,要求能多次向浏览器写入内容,且写入的内容可被浏览器即时执行。由于后续写入的任务依赖之前输出的内容,计划通过for循环调用w.Write()分块写入数据。
初始示例代码如下:
func Handler(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "text/html") w.WriteHeader(200) w.Write([]byte("<script>performance.mark('start')</script>")) time.Sleep(time.Second) w.Write([]byte("<script>performance.mark('end')</script>")) w.Write([]byte("<script>performance.measure('Time between', 'start', 'end')</script>")) }
我原本预期性能测量值约为1秒——毕竟start标记比end标记早1秒写入,但实际情况是浏览器要等完整响应接收完毕才会渲染执行,导致测量结果不符合预期。
后续发现Go标准库的http.ResponseWriter本身不具备刷新输出响应的能力,但它的底层结构体实现了.Flush()方法。修改后的代码可以正常实现即时执行的需求,但写法不够优雅:
func Handler(w http.ResponseWriter, r *http.Request) { var wf = w.(interface{ Flush() }) // 类型断言获取Flush能力 w.Header().Add("Content-Type", "text/html") w.WriteHeader(200) w.Write([]byte("<script>performance.mark('start')</script>")) wf.Flush() // 刷新输出至浏览器 time.Sleep(time.Second) w.Write([]byte("<script>performance.mark('end')</script>")) w.Write([]byte("<script>performance.measure('Time between', 'start', 'end')</script>")) }
内容的提问来源于stack exchange,提问作者David Alsh
相关产品推荐
相关产品推荐

