Revel的Flash消息仅在重定向后的下一个GET请求中有效且用完即删;必须配合c.Redirect()使用,不能与c.Render()混用,模板需显式读取如{{.flash.success}},key区分大小写且不可含冒号。

Revel 的 Flash 消息不是“设了就能显示”,它只在重定向后的下一个 GET 请求中有效,且用完即删;不配合 c.Redirect()、或模板没读 {{.flash.success}},消息就彻底消失。
为什么 c.Flash.Success() 后直接 c.Render() 不显示?
因为 Flash 本质是写入一个带签名的 cookie(REVEL_FLASH),仅对下一次 HTTP 请求生效。而 c.Render() 是服务端模板渲染,不触发新请求,.flash 上下文为空。
- ✅ 正确流程:POST 处理 →
c.Flash.Success("OK")→c.Redirect(App.ShowSettings)→ 浏览器发起新 GET →ShowSettings中调用c.Render()→{{.flash.success}}可读 - ❌ 错误写法:
c.Flash.Error("xxx"); return c.Render("form.html")→ 模板里{{.flash.error}}始终为空 - ⚠️ 注意:
c.Redirect()返回的是 302 响应,必须由浏览器完成跳转,中间不能被 JS 拦截或替换成fetch+ 手动渲染
{{.flash.key}} 模板取值的大小写和命名规则
Flash 的 key 区分大小写,且禁止含冒号;模板中访问的 key 必须与后端设置的 key 完全一致。
-
c.Flash.Success("Saved!")→ 模板用{{.flash.success}}(小写 s),不能写{{.flash.Success}} -
c.Flash.Out["notice"] = "Done"→ 模板用{{.flash.notice}} - 禁止 key 含冒号:
c.Flash.Out["user:email"]会 panic 报错Key may not have a colon,应改用user_email - 建议始终先判断存在再输出:
{{if .flash.error}}<div class="alert">{{.flash.error}}</div>{{end}},避免空字符串占位
验证失败时如何连带表单值一起传回?
单纯设 c.Flash.Error() 不够,用户重新提交还得再输一遍内容;必须配合 c.Validation.Keep() 和 c.FlashParams() 才能保留原始参数。
-
c.Validation.Keep():把验证错误结构序列化进 Flash cookie -
c.FlashParams():把当前请求的 URL 参数、表单字段(username、email等)也存进 Flash,模板中可通过{{.flash.username}}取回 - 缺一不可:漏掉
.Keep(),{{.errors.username.Message}}为空;漏掉.FlashParams(),input 的value="{{.flash.username}}"就是空 - 模板中字段级错误要写成:
{{if .errors.username}}<small>{{.errors.username.Message}}</small>{{end}},这里的username是 Go 变量名,不是 HTML 的name属性值
Flash 消息丢了?检查这三处硬性依赖
Flash 不是独立模块,它依赖 Revel 的 Filter 链、Session 初始化和 Cookie 配置,任一环节断开都会静默失效。
-
revel.FlashFilter必须在revel.SessionFilter之后、revel.ActionInvoker之前 —— 查 app/init.go 的revel.Filters切片顺序 - 确认
conf/app.conf中未禁用:flash.cookie.enabled = true(默认为 true,但有人会手动关) - 确保 Session 已启用且可写:如果
c.Session.Get("uid")都返回空,c.Flash很可能也为 nil 或写入失败 - 不要试图延长 Flash 生命周期:cookie 默认随浏览器关闭失效,无法设
Max-Age;需要持久提示请改用Session+ 手动清理逻辑
最常被忽略的一点:Flash 数据不会自动清空或自动渲染。它只是一次性载荷,你得在目标模板里显式读、显式输出,并依赖下一次请求自然丢弃——跳转链多走一步(A → B → C),C 就收不到 A 设的 Flash。


















