Revel模板中通过{{.flash.key}}读取Flash消息,如{{.flash.success}}或{{.flash.error}};需确保控制器调用c.Flash.Success()等方法设值,且key全小写、用点号访问,不可写为flash_success或Flash.Success。

模板里怎么读取.flash里的消息
Revel模板中Flash消息通过.flash上下文变量访问,它本质是上一个请求存入的字符串映射(map[string]string)。你不能直接写{{.flash}}打印整个结构,必须指定key,比如{{.flash.success}}或{{.flash.error}}。
常见错误是把key写成flash_success或Flash.Success——Revel只认小写点号路径,且key由你在控制器里调用c.Flash.Success()或c.Flash.Error()时传入的字符串决定。如果你写c.Flash.Set("notice", "操作完成"),那模板里就得用{{.flash.notice}}。
-
c.Flash.Success("Saved!")→ 模板用{{.flash.success}} -
c.Flash.Error("Invalid input")→ 模板用{{.flash.error}} -
c.Flash.Set("warning", "请确认邮箱")→ 模板用{{.flash.warning}}
c.FlashParams()和c.Validation.Keep()对.flash的影响
这两个方法不往.flash里塞success或error,而是把表单参数和验证错误“透传”到下个请求的.flash和.errors里。漏掉它们,用户重定向回来后既看不到错误提示,也填不上上次输的内容。
c.FlashParams()把c.Params里所有值复制进.flash,所以{{.flash.username}}能回显输入框;c.Validation.Keep()把Validation.ErrorMap序列化进Flash cookie,让{{.errors.username.Message}}可读。二者都依赖FlashFilter在请求开始时自动恢复数据,所以必须确保conf/app.conf里flash.cookie.name已配置且未被禁用。
- 没调
c.Validation.Keep()→{{.errors}}为空,字段级错误不显示 - 没调
c.FlashParams()→{{.flash.username}}为空,input value丢失 - 两个都没调 → 表单提交失败后页面像第一次加载一样干净,用户得重填全部
Flash消息的生命周期和并发风险
Flash是“一次有效”的cookie:它在当前请求被读取后,会在响应结束前自动清空(Flash.Out被丢弃,Flash.Data保留至下个请求)。这意味着如果你在模板里用了{{.flash.success}},这个值在本次渲染后就没了;但如果模板没读它,下次请求还会出现——这不是bug,是设计使然。
容易被忽略的是并发场景:用户快速连点两次提交按钮,可能触发两个c.Redirect(),第二个会覆盖第一个的Flash内容。Revel不提供原子写入或队列机制,所以不要依赖Flash做关键状态通知(比如支付结果),只用于UI提示。
- Flash消息不会跨tab共享,每个浏览器tab有自己的Flash cookie
- 如果重定向目标Action没调
c.Render()(比如返回c.Redirect()嵌套),.flash不会被消费,下次仍可见 - 4KB大小限制适用于整个Flash cookie,存大段HTML或JSON容易溢出,应只放纯文本
模板里怎么安全地渲染Flash并避免空格/换行污染
Go模板默认保留空白符,{{.flash.success}}前后若有换行或空格,会原样输出到HTML里,可能破坏布局。最稳妥的做法是用{{with}}包裹,并加trimSpace函数(Revel内置):
{{with .flash.success}}<div class="alert alert-success">{{trimSpace .}}</div>{{end}}
注意trimSpace只处理首尾空白,不删中间空格。如果你存的消息本身含
或
标签,得自己转义或用{{. | safeHTML}}——但别对用户输入直接safeHTML,有XSS风险。
- 永远用
{{with}}判断存在性,避免{{.flash.success}}为空时输出空- 不要在
{{if .flash.error}}里再嵌套{{.flash.error}},模板解析器会报错- 多个Flash key同时存在时(如
success和warning),它们互不影响,按需分别with - 不要在


















