- Published on
go实现http流式输出
- Authors
- Name
- liuxiaobo
golang
package main
import (
"fmt"
"log"
"net/http"
"time"
)
func main() {
// 设置路由
http.HandleFunc("/stream", handleStream)
// 启动服务器
fmt.Println("服务器启动在 http://localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
func handleStream(w http.ResponseWriter, r *http.Request) {
// 设置响应头,支持流式输出
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
w.Header().Set("Access-Control-Allow-Origin", "*")
// 富文本示例
text := `
<h1>欢迎使用富文本打字机效果</h1>
<p>这是一个支持 <span class="highlight">HTML标签</span> 的示例。</p>
<p>你可以使用 <code class="code">代码块</code> 来显示代码。</p>
<p>这是一个 <a href="#" class="link">链接</a> 示例。</p>
<p>支持 <strong>加粗</strong> 和 <em>斜体</em> 文本。</p>
<ul>
<li>列表项 1</li>
<li>列表项 2</li>
<li>列表项 3</li>
</ul>
`
// 将文本按行分割
for _, char := range text {
// 发送单个字符
fmt.Fprintf(w, "data: %s\n\n", string(char))
w.(http.Flusher).Flush()
time.Sleep(50 * time.Millisecond)
}
}
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>打字机效果演示</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
}
#output {
font-size: 24px;
padding: 20px;
background-color: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
max-width: 800px;
min-height: 200px;
white-space: pre-wrap;
}
button {
position: fixed;
top: 20px;
padding: 10px 20px;
font-size: 16px;
background-color: #4caf50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
/* 富文本样式 */
.highlight {
color: #e74c3c;
font-weight: bold;
}
.code {
background-color: #f8f9fa;
padding: 2px 4px;
border-radius: 3px;
font-family: monospace;
}
.link {
color: #3498db;
text-decoration: underline;
}
/* 确保列表样式正确显示 */
ul {
margin: 10px 0;
padding-left: 20px;
}
li {
margin: 5px 0;
}
</style>
</head>
<body>
<button onclick="startStream()">开始显示</button>
<div id="output"></div>
<script>
function startStream() {
const output = document.getElementById('output')
output.innerHTML = ''
const eventSource = new EventSource('http://localhost:8080/stream')
eventSource.onmessage = function (event) {
// 使用innerHTML来支持HTML标签
// TODO: 不支持HTML标签
output.innerHTML += event.data
// 自动滚动到底部
output.scrollTop = output.scrollHeight
}
eventSource.onerror = function () {
eventSource.close()
}
}
</script>
</body>
</html>