revel 的 flash 仅在重定向后的下一个 get 请求中有效且用完即删;必须配合 redirect 使用,不能与 render 混用,模板需显式读取如 {{.flash.success}},key 区分大小写且不可含冒号。

Revel 的 Flash 不是“存了就能显示”,它只在重定向后的下一个 GET 请求中有效,且用完即删——跳转前不调 c.Flash.Success() 或 c.Flash.Error(),或者跳转后模板没读 {{.flash.success}},消息就彻底消失。
Flash 必须配合 Redirect 使用,不能和 Render 混用
Revel 的 Flash 本质是写入一个带签名的 cookie(REVEL_FLASH),仅对下一次 HTTP 请求生效。如果处理完 POST 后直接 c.Render(),页面没刷新、没新请求,.flash 在模板里就是空的。
- ✅ 正确:POST 处理完 → 调用
c.Flash.Success("xxx")→c.Redirect(App.ShowSettings) - ❌ 错误:POST 处理完 →
c.Flash.Error("xxx")→c.Render("form.html")(用户看不到) - ⚠️ 注意:
c.Redirect()触发的是 302 响应,浏览器发起新的 GET 请求,这时.flash才被 Revel 自动注入模板上下文
模板里取 Flash 数据要先判断 key 是否存在
Flash 是个结构体,包含 Data(上一个请求传来的值)和 Out(当前请求准备写入的值)。模板访问的是 Data,但字段名必须和你设的 key 完全一致,且大小写敏感。
- 用
c.Flash.Success("Saved!")→ 模板写{{.flash.success}}(小写 s) - 用
c.Flash.Out["notice"] = "Done"→ 模板写{{.flash.notice}} - 不判断直接输出会渲染空字符串,建议加条件包裹:
{{if .flash.error}}<div class="alert alert-danger">{{.flash.error}}</div>{{end}}
Flash cookie 有大小限制和字符限制
Revel 把整个 Flash 序列化为一个签名 cookie,所以受浏览器 cookie 限制(通常 4KB 上限),而且 key 名里不能含冒号 :——否则运行时报错 Key may not have a colon。
- 避免用
c.Flash.Out["user:email"],改用c.Flash.Out["user_email"] - 大段文本(如长错误详情)别硬塞进 Flash,容易超限;可改存 session ID 或日志追踪号,再在服务端查详情
- cookie 默认随浏览器关闭失效,不支持自定义过期时间;如需持久化提示,得自己用
Session+ 手动清理逻辑
最常漏的一点:以为 Flash 会自动清空或自动渲染。它不会——你得在模板里显式读取、输出、并依赖下一次请求自动丢弃。一旦跳转链变长(比如 A → B → C),C 页面就收不到 A 设的 Flash,中间多了一次请求,数据就没了。











