如何使用Golang开发简单投票系统_Golang Web应用实战

1次阅读

go 用 net/http 可构建轻量投票系统:用 sync.map 或 mutex 保障计数并发安全,通过一次性 Token 防重复投票,jsON 接口返回实时结果并前端轮询,Nginx 反向代理部署、静态文件安全暴露、panic 恢复中间件保障稳定性。

如何使用Golang开发简单投票系统_Golang Web应用实战

Go 本身不带 Web 框架,但 net/http 足够支撑一个轻量、可控的投票系统——关键不在“用什么框架”,而在如何组织状态、防止重复投票、避免竞态。

如何用 net/http 处理投票提交与计数

别急着上 gorilla/muxgin。原生 http.ServeMux + 闭包结构体方法就能清晰分离逻辑:

  • http.HandleFunc("/vote", handleVote):接收 POST,解析 id=option1 表单
  • 计数器必须是并发安全的:sync.Map 存选项 → 计数值,或用 sync.Mutex 包裹普通 map[String]int
  • 不要在 handler 里直接操作全局 map——把计数逻辑抽成方法,比如 voter.Increment("option1")
  • 返回 jsonContent-Type: application/json)比跳转更利于前端控制反馈

如何防止用户重复投票(无登录场景)

没有账号体系时,“防重”本质是降低作弊成本,而非绝对阻止:

  • 服务端用 net/http.Request.RemoteAddr + User-Agent 做粗粒度标记(仅限演示,不可用于生产)
  • 更可行的是:写入临时 cookiehttp.Setcookie(rw, &http.Cookie{Name: "voted", Value: "true", MaxAge: 3600})),前端禁止再次点击按钮
  • 真正有效的方案是加简单 Token:GET /vote/token 返回一次性 token=abc123,提交时带上,服务端用 sync.Map 标记已使用并立即删除
  • 注意:别用时间戳或自增 ID 当 token,容易被枚举

如何让选项列表和结果实时一致

页面每次刷新都走一次 GET /results 是最简单的同步方式,无需 websocket

立即学习go语言免费学习笔记(深入)”;

  • 接口返回 JSON:{"option1": 42, "option2": 19, "total": 61}
  • 前端用 fetch() 定期轮询(如每 5 秒),更新 dom 中的数字 —— 对投票系统足够及时
  • 如果用模板渲染(html/template),务必在 Execute 前从共享计数器读取最新值,别缓存 template 输出
  • 避免在 HTML 中硬编码初始票数;所有数据应由后端注入或通过 API 获取

部署时最容易忽略的三个点

本地跑通 ≠ 可上线:

  • http.ListenAndServe(":8080", nil) 在服务器上要绑定 :80?别直接提权,用反向代理(nginx)转发,Go 进程仍跑 :8080
  • 静态文件(css/JS)别用 http.FileServer 直接暴露整个目录,易泄露源码;明确指定子路径:http.Handle("/Static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))
  • 没做 panic 恢复?加一层 middleware:defer func() { if r := recover(); r != nil { log.printf("panic: %v", r) } }(),否则一次空指针就 kill 整个 server

真正的复杂点不在“怎么投”,而在于“谁投过、什么时候失效、数据怎么落地”。内存计数重启即丢,真要持久化,就得对接 sqliteredis —— 那已经是下一个迭代的事了。

text=ZqhQzanResources