buffalo表单提交必须显式注册post路由并配置form tag、csrf token及错误渲染路径,缺一不可;否则将404、405或403失败。

Buffalo 表单提交必须用 POST 路由,不能只靠 HTML form 默认行为
Buffalo 默认禁用对未注册 HTTP 方法的处理,哪怕你写了 <form method="post"></form>,如果路由没显式声明 POST,请求会直接 404 或 405。这是新手最常卡住的地方。
实操上,先在 app.go 中注册路由:
app.Post("/users", UsersCreate)
再确保 handler 函数签名匹配 Buffalo 的上下文要求:
func UsersCreate(c buffalo.Context) error {
u := &User{}
if err := c.Bind(u); err != nil {
return err
}
// 处理保存逻辑...
return c.Redirect(302, "/users")
}
-
c.Bind()会自动解析application/x-www-form-urlencoded和multipart/form-data请求体,但字段名必须与 struct tag 匹配(如json:"name"不起作用,要用form:"name") - 如果表单含文件上传,
c.Bind()仍可用,但需确保 HTML 中enctype="multipart/form-data"已设置 - 不推荐在 handler 里手动调用
c.Request().ParseForm()——c.Bind()已封装好,重复解析可能丢数据
表单字段名必须和 struct 字段的 form tag 严格一致
Buffalo 的 c.Bind() 不看 json tag,只认 form tag。哪怕你的 struct 是为 API 设计的,表单提交时也得补上这层映射。
比如后端 struct:
type User struct {
ID int `db:"id" json:"id"`
Name string `db:"name" json:"name" form:"name"`
Email string `db:"email" json:"email" form:"email"`
}
对应 HTML 表单必须写成:
Buffalo框架 1.0.1 版本源码包下载,适合需要错误处理改进、依赖更新、render.Download 注释和 request logger 调整的 v1 项目。
<input name="name" value="Alice"><input name="email" value="a@example.com">
- 若漏写
form:"xxx",字段值不会被绑定,u.Name保持空字符串或零值 - 字段名含点号(如
profile.name)或中括号(如roles[0])时,c.Bind()不支持嵌套解析 —— Buffalo 原生只做一层平铺绑定 - 需要嵌套结构?改用 JSON 提交 +
c.BindJSON(),或手动从c.Request().PostForm取值
验证失败时保留表单数据并显示错误,别直接重定向
用 c.Redirect() 返回错误页会导致所有已填字段清空,用户体验极差。Buffalo 推荐用 c.Render() 原路返回,并把错误和原始数据塞进 context。
典型写法:
func UsersCreate(c buffalo.Context) error {
u := &User{}
if err := c.Bind(u); err != nil {
return err
}
verrs := validate.New()
if u.Name == "" {
verrs.Add("name", "Name is required")
}
if u.Email == "" {
verrs.Add("email", "Email is required")
}
if verrs.HasAny() {
c.Set("user", u)
c.Set("errors", verrs)
return c.Render(422, r.HTML("users/new.html"))
}
// 保存成功逻辑...
return c.Redirect(302, "/users")
}
-
c.Set("user", u)是关键 —— 它让模板能回填u.Name、u.Email,避免用户重输 - 模板里用
<input name="name" value="<%= user.Name %>">回显;错误提示用 - 别在验证失败时调用
c.Redirect(),那会丢失user和errors数据
CSRF 保护默认开启,表单必须带 authenticity_token
Buffalo 默认启用 CSRF 防护,所有 POST/PUT/DELETE 请求都需携带有效 token,否则返回 403。这不是可选项,是强制行为。
模板中必须插入:
<input name="authenticity_token" type="hidden" value="<%= authenticity_token() %>">
这个 helper 函数由 Buffalo 自动注入,无需额外 import。
- 如果手写表单但忘了这行,请求一定失败,错误信息是
Forbidden: invalid authenticity token - 用
buffalo-pop生成的 CRUD 模板已自带该字段,但自定义表单容易遗漏 - 禁用 CSRF(不推荐)需在
app.go中调用app.Use(csrf.Middleware(false)),仅限调试或内部工具
form tag 和 authenticity_token —— 这两个一漏,整个提交链就断在第一环。










