Go服务端接收POST请求时无刷新更新HTML页面的实现方案
实现无刷新更新页面内容的Go服务器方案
问题背景
我正在编写一个支持GET和POST请求的Go服务器,目前GET请求能正常返回HTML页面,POST请求可以接收JSON数据,但只能通过刷新整个页面来更新展示POST接收的数据,希望实现接收POST请求时无需刷新页面就能更新HTML内容。
Go后端修改
需要新增API接口供前端异步获取最新数据,同时优化请求处理逻辑:
func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // 处理POST请求 if r.Method == "POST" { b, err := io.ReadAll(r.Body) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } event := r.URL.Query().Get("event") switch event { case "up": err = h.up(b) case "join": err = h.join(b) default: fmt.Printf("事件%s对应的处理器未实现 \n", event) http.Error(w, "未实现的事件类型", http.StatusBadRequest) return } if err != nil { fmt.Printf("请求方法'%s'返回错误:%s\n", event, err) http.Error(w, err.Error(), http.StatusInternalServerError) return } // POST请求处理完成后返回成功响应 w.WriteHeader(http.StatusOK) return } // 处理GET请求 switch r.URL.Path { case "/": // 加载并渲染网页模板 tmpl := template.Must(template.ParseFiles("layout.html")) tmpl.Execute(w, data) case "/api/devices": // 新增API接口,返回最新的设备数据JSON w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(data.Dispositivos) default: http.NotFound(w, r) return } }
修改说明
- 拆分POST与GET请求处理逻辑,结构更清晰
- 新增
/api/devices接口,专门返回设备数据的JSON格式,供前端异步获取 - 完善错误处理,返回标准HTTP状态码,避免直接panic
前端HTML修改
修改<script>部分,通过异步请求获取最新数据并动态更新页面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="author" content="Jorge Felipe González Orellana"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> *{ box-sizing: border-box; padding: 0; margin: 0; } body { background-color: #7A82AB; color: floralwhite; font-family: Arial, Helvetica, sans-serif; margin: 0; } .nav-grnl { display: flex; align-items: center; justify-content: center; background-color: #333333; height: 7vh; } .nav-grnl a { margin: 10px 10px 10px 10px; padding: 8px 16px; display: flex; text-decoration: none; color: floralwhite; border-radius: 12px; } .nav-grnl a:hover { color: black; background-color: floralwhite; } .logo { display: flex; position: fixed; left: 0; height: inherit; width: 7vh; } .contenedor-gnrl { display: grid; position: fixed; grid-template-areas: 'left right'; width: 100vw; height: 88vh; } .main-section { background-color: floralwhite; color: black; grid-area: left; width: 80vw; } .main-info { background-color: #999792; color: black; grid-area: right; width: 20vw; } .footer-gnrl { background-color: #333333; display: flex; align-items: center; justify-content: center; position: fixed; bottom: 0; width: 100vw; height: 5vh; } p { margin: 0; border: 0; padding: 0; } @media (max-width: 600px) { .grid-container { grid-template-areas: 'header header' 'left left' 'right right' 'footer footer'; } } </style> <title>2veinte test</title> <script> // 定时获取最新设备数据并更新页面 setInterval(updateDevices, 1000); function updateDevices() { fetch('/api/devices') .then(response => response.json()) .then(devices => { const container = document.getElementById('DispositivosLoraWAN'); // 清空现有内容 container.innerHTML = ''; // 遍历设备数据生成新DOM元素 devices.forEach(device => { const deviceDiv = document.createElement('div'); deviceDiv.innerHTML = ` <h6>${device.Nombre_Disp}</h6> <h6>${device.DevEUI}</h6> <h6>${device.Data}</h6> `; container.appendChild(deviceDiv); }); }) .catch(error => console.error('获取设备数据失败:', error)); } </script> </head> <body> <div class="nav-grnl"> <svg class="logo"></svg> <a href="/">Link</a> <a href="/">Link</a> <a href="/">Link</a> </div> <div class="contenedor-gnrl"> <div class="main-section"> <div class="DispositivosLoraWAN" id="DispositivosLoraWAN"> <!-- 内容由JS动态生成 --> </div> </div> <div class="main-info"> <p>主信息</p> </div> </div> <div class="footer-gnrl"> <p>页脚</p> </div> </body> </html>
修改说明
- 使用
fetchAPI异步请求后端/api/devices接口获取最新数据 - 每次获取数据后,清空容器并重新生成DOM元素,实现无刷新更新
- 移除模板中的静态循环渲染,改为JS动态生成内容
内容的提问来源于stack exchange,提问作者Jorge
相关产品推荐
相关产品推荐

