使用htmx表单向Gin服务器传值:无法正确读取请求体
问题:使用htmx json-enc扩展向Gin服务器传递表单值的正确方式
我用带json-enc扩展的htmx表单,想把第一个输入框的todo值发送到Gin服务器,但后端获取请求体时得到的是URL编码的字节数组,不是JSON格式。
前端代码:
<form hx-post="/addToDo" hx-ext="json-enc" hx-trigger="submit" hx-target="#todos" hx-swap="outerHTML"> <input type="text" placeholder="todo" name="todo" /> <input type="submit" /> </form> <ol id="todos"></ol>
Gin后端代码:
r.POST("/addToDo", func(c *gin.Context) { fmt.Println(c.Request.Body) // 输出: &{0xc0000b2000 <nil> <nil> false true {0 0} false false false 0xeaee20} jsonData, err := ioutil.ReadAll(c.Request.Body) if err != nil { fmt.Println("something went wrong here boys") return } fmt.Println(jsonData) // 输出: [116 111 100 111 61 104 101 108 108 111] })
我不想用URL参数传递,确定可以通过请求体实现,想知道怎么正确获取请求体或todo输入值?
解决方案
问题根源
你看到的字节数组是todo=hello的URL编码形式,说明json-enc扩展没有生效,表单还是以默认的application/x-www-form-urlencoded格式发送请求,而非JSON格式。
步骤1:确保正确引入json-enc扩展
必须在htmx核心库之后加载json-enc扩展脚本,否则扩展无法被htmx识别:
<script src="https://unpkg.com/htmx.org@1.9.10"></script> <script src="https://unpkg.com/htmx.org/dist/ext/json-enc.js"></script>
步骤2:后端解析JSON格式请求
当json-enc生效后,请求体将是{"todo": "你的输入值"}这种JSON结构,用Gin的ShouldBindJSON方法可以轻松解析:
首先定义对应结构体:
type TodoRequest struct { Todo string `json:"todo"` // 字段名要和表单name一致,json标签对应JSON键名 }
然后修改处理函数:
import "net/http" // ... r.POST("/addToDo", func(c *gin.Context) { var req TodoRequest // 解析JSON请求体到结构体 if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "请求格式错误"}) return } // 成功获取todo值 fmt.Println("收到的todo内容:", req.Todo) // 这里可以添加业务逻辑,比如保存到数据库 // 然后返回更新后的todos列表(对应hx-target的#todos) c.HTML(http.StatusOK, "todos_partial.html", gin.H{ "todos": []string{req.Todo}, // 示例数据,实际替换为真实列表 }) })
备选方案:直接解析表单格式(无需json-enc)
如果暂时不想用JSON格式,也可以跳过json-enc,直接用Gin的PostForm方法获取表单值,这种方式更简单:
r.POST("/addToDo", func(c *gin.Context) { // 直接通过表单name获取值 todo := c.PostForm("todo") if todo == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "todo不能为空"}) return } fmt.Println("收到的todo内容:", todo) // 处理逻辑... })
内容的提问来源于stack exchange,提问作者AyeAreEm
相关产品推荐
相关产品推荐

