put请求体收不到数据是因content-type未设置、中间件提前读取body或结构体字段未导出;header需用c.request().header.get()获取;oauth state失败常因未调save()或session存储配置不当;路由参数缺失多因http方法错配;模型更新失败系字段未大写或缺db标签。

PUT请求体收不到数据,别急着骂框架
Buffalo默认不解析PUT请求体,你发的表单或JSON字段全被丢进黑洞里——这不是bug,是设计选择。
第一步:确认前端是否设置了正确的Content-Type。用fetch发PUT时浏览器不会自动加application/json,必须显式写上headers: {"Content-Type": "application/json"},否则后端当二进制流处理,Bind直接失败。
第二步:检查中间件有没有提前读取Body。比如日志中间件调了io.ReadAll(c.Request().Body)但没把body塞回去,后续c.Bind(&u)就永远拿不到数据——这是最隐蔽也最常踩的坑。
第三步:结构体字段必须大写且带json标签,例如type User struct { Name string `json:"name"` },小写name字段Bind后永远为空。
这一步操作起来很简单,直接把文件拖进去就行。
Header参数取不到?先看是不是走错了路
想从Header里读X-User-ID却总拿到空字符串,问题大概率出在方法选错——c.Param()和c.QueryParam()根本不管Header,它们只处理URL路径和查询参数。
正确方式只有一种:【c.Request().Header.Get("X-User-ID")】。Header名不区分大小写,Get("x-user-id")和Get("X-User-ID")效果一样;若Header不存在,返回空字符串而非nil,不用额外判空。
注意:如果Nginx反向代理转发请求,默认会过滤掉自定义Header。必须在Nginx配置里加proxy_set_header X-User-ID $http_x_user_id;,否则Header根本到不了Buffalo。
OAuth登录state校验失败,session可能没存住
GitHub回调时提示state mismatch,不是GitHub配置错了,而是Buffalo session没生效。
Buffalo框架 1.0.1 版本源码包下载,适合需要错误处理改进、依赖更新、render.Download 注释和 request logger 调整的 v1 项目。
方法一:确保调用c.Session().Set("oauth_state", state)后立即执行c.Session().Save(),缺这句session数据不会持久化,回调时取出来就是nil。
方法二:检查session存储后端。默认使用cookie store,但若应用部署在多实例环境且没共享密钥,session签名会校验失败——此时要换成Redis等外部store,并统一设置SessionStoreKey。
这一步不能跳过,否则CSRF防护形同虚设。
路由参数取不到,可能是HTTP方法写错了
你在浏览器地址栏敲http://localhost:3000/users/123,后端却收不到id参数,第一反应是路由定义有问题,其实更可能是HTTP方法用错了。
检查路由注册代码:必须是app.GET("/users/{id}", h.ShowUser),而不是app.Post("/users/{id}", h.ShowUser)。POST路由不会匹配GET请求,{id}自然无法解析。
另外,Nginx或Caddy反向代理有时会把PUT/DELETE重写成POST,用c.Request().Method打印出来确认真实方法,比猜快得多。
模型字段更新失败,导出规则被忽略了
调用u.Update()后数据库字段纹丝不动,不是ORM有bug,而是Go的导出规则在起作用。
Buffalo的Pop ORM只操作首字母大写的字段。如果你定义type User struct { name string },这个name字段永远不会被写入数据库——改成Name string才能被识别。
还有个隐藏条件:字段必须有db标签,比如Name string `db:"name"`,否则即使大写也不会映射到列名。










