Go HTTP 服务端需根据请求 Content-Type 区分处理:application/json 用 json.Decoder,application/x-www-form-urlencoded 则应使用 r.FormValue 或 r.ParseForm(),直接对表单请求调用 JSON 解码必然失败。
go http 服务端需根据请求 content-type 区分处理:`application/json` 用 `json.decoder`,`application/x-www-form-urlencoded` 则应使用 `r.formvalue` 或 `r.parseform()`,直接对表单请求调用 json 解码必然失败。
在 Go Web 开发中,一个常见误区是试图用统一的 json.NewDecoder(r.Body).Decode(&v) 处理所有 POST 请求——这在 curl 或 httpie 发送 JSON 数据时能正常工作,但在浏览器原生
<script> function submitAsJson(e) { e.preventDefault(); const form = e.target; const data = Object.fromEntries(new FormData(form)); fetch('/register', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }) .then(r => r.ok ? alert('Success') : alert('Error')); } </script>? 关键总结
- 不要假设所有 POST 都是 JSON:浏览器表单默认是 x-www-form-urlencoded,这是 HTTP 规范行为;
- 避免重复读取 r.Body:r.ParseForm() 会消耗 Body,后续 json.Decoder 将读到空流;若需同时支持多种格式,应在分支逻辑中分别处理(如先检查 Content-Type,再决定调用 ParseForm 还是 json.Decode);
- 始终验证输入:无论哪种格式,都应校验必填字段、邮箱格式、密码强度等,json.Decode 成功 ≠ 数据合法;
- 调试技巧:打印 r.Header.Get("Content-Type") 和 io.ReadAll(r.Body)(注意:仅用于调试,生产勿用,因会消耗 Body)可快速定位格式问题。
通过区分协议语义并适配对应解码逻辑,即可彻底解决“浏览器提交失败而命令行成功”的典型陷阱。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










