flash消息必须走重定向才能在模板中读到,因revel的flash依赖post/redirect/get模式:仅c.redirect()后的下个get请求调用c.render()时,{{.flash.key}}才注入上下文;直接c.render()会丢失所有flash.out内容。

Flash消息必须走重定向才能在模板中读到
Revel的Flash不是普通变量,它依赖Post/Redirect/Get模式:只有调用c.Redirect()后,下一次GET请求的模板里才能访问{{.flash.key}}。直接c.Render()会丢失所有Flash.Out内容——因为Flash数据只写入Cookie并标记为“已消费”,不经过Render上下文透传。
常见错误现象:c.Flash.Success("OK")后直接return c.Render(),模板里{{.flash.success}}始终为空。
- 必须搭配
c.Redirect()使用,例如return c.Redirect(App.ShowSettings) - Flash数据在重定向后的目标Action里调用
c.Render()时才注入模板上下文 - 如果目标Action没调用
c.Render()(比如返回JSON或文件),.flash也不会生效
Flash.Error和Flash.Success只是快捷写法
c.Flash.Error("用户名不能为空")等价于c.Flash.Out["error"] = "用户名不能为空";同理Success对应"success"键。模板中必须用对应key访问:{{.flash.error}}或{{.flash.success}},不能写成{{.flash.Error}}或{{.flash.message}}。
如果你需要自定义key(比如"validation"或"notice"),直接赋值即可:c.Flash.Out["validation"] = "邮箱格式错误",模板中用{{.flash.validation}}取值。
- Flash只支持字符串值,传struct或map会转成
"{...}"字面量 - key名区分大小写,
"Error"和"error"是两个不同键 - 同一个key多次赋值,以后写入为准(后覆盖前)
Flash模块必须启用且Filter顺序不能错
Revel默认启用FlashFilter,但如果你修改过app/init.go里的revel.Filters切片,要确认revel.FlashFilter在revel.SessionFilter之后、revel.ActionInvoker之前。否则c.Flash对象可能为nil或无法写入Cookie。
典型错误配置:revel.FlashFilter被误删,或放在revel.SessionFilter之前——导致Session未初始化就尝试读写Flash Cookie,引发panic或静默失败。
- 检查
conf/app.conf中是否禁用了Flash:flash.cookie.enabled = false(默认true) - Flash Cookie默认有效期为0(即浏览器关闭失效),不可手动延长,也不支持设置
Max-Age - Flash数据上限约4KB,但实际建议单条消息控制在1KB以内,避免Cookie超限被截断
模板里读不到Flash?先检查这三处
最常被忽略的是Flash数据依赖Session Cookie解密。Nginx反代时若漏传X-Forwarded-Proto,会导致Session解密失败,连带Flash数据无法还原——此时{{.flash.xxx}}全为空,且无任何错误日志。
- 开发时用
curl -v http://localhost:9000/your-path看响应头是否含Set-Cookie带REVEL_FLASH - 部署Nginx后,必须加
proxy_set_header X-Forwarded-Proto $scheme;,否则HTTPS下Flash失效 - 模板中不要用
{{if .flash}}...{{end}}判断整体是否存在——.flash永远是非nil空map,应判断具体key:{{if .flash.error}}











