You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HTMX+Go应用MongoDB文档字段为空及请求体读取错误解决

问题:HTMX表单数据存入MongoDB Atlas为空的排查与解决

问题现象

尝试将HTMX表单数据发送到Go服务器,再通过Go将文档添加至MongoDB Atlas云数据库,数据库中文档的表单字符串字段全部为空,但文档能成功创建。

前端HTMX代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>createReminder</title>
    <script src="https://unpkg.com/htmx.org@1.9.9/dist/htmx.js"></script>
    <link href="/server-side/output.css" rel="stylesheet"> 
</head>
<body hx-target="this">
    <div class="topbar">
        <a hx-get="/" trigger="click" >Page 1</a>
        <a hx-get="/createNewEvent" trigger="click">Page 2</a>
    </div>
    <div class="newEventForm">
    <form hx-post="/createNewEvent">
    <p>Enter a title: </p>
    <input type="text" name="title">
    <input type="hidden" name="currentDate" id="currentDate" value="">
    <p>When date does the event take place?</p>
    <input type="date" name="eventDate">
    <button type="submit">Submit</button>
</form>
</div>
</body>
</html>

Go服务器代码

package main

import (
    "context"
    "fmt"
    "net/http"
    "path/filepath"

    "go.mongodb.org/mongo-driver/bson/primitive"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

type Event struct {
    ID          primitive.ObjectID `bson:"_id,omitempty"`
    Title       string             `bson:"title"`
    CurrentDate string             `bson:"currentDate"`
    EventDate   string             `bson:"eventDate"`
}

type User struct {
    ID primitive.ObjectID `bson:"_id,omitempty"`
}

var client *mongo.Client
var DBError error
var userId primitive.ObjectID
var newUser bool = false

func mainPage(w http.ResponseWriter, r *http.Request) {

    if newUser == false {
        id := primitive.NewObjectID()
        document := User{
            ID: id,
        }
        collection := client.Database("MyMongoDB").Collection("Users")
        _, err := collection.InsertOne(context.TODO(), document)

        if err != nil {
            fmt.Println("Error inserting User")
        }
        fmt.Println("User with Id :", id.String(), "inserted successfully")
        newUser = true
        userId = id
    }
    filepath := filepath.Join("client-side", "html", "index.html")
    http.ServeFile(w, r, filepath)
}

func newEventPage(w http.ResponseWriter, r *http.Request) {
    filepath := filepath.Join("client-side", "html", "createNewEvent.html")
    http.ServeFile(w, r, filepath)

    if r.Method == http.MethodPost {
        handleFormSubmit(r)
    }
}

func serveCSS(w http.ResponseWriter, r *http.Request) {
    filepath := filepath.Join("server-side", "output.css")
    http.ServeFile(w, r, filepath)
}

func handleFormSubmit(request *http.Request) {

    request.ParseForm()

    collection := client.Database("MyMongoDB").Collection("Events")

    document := Event{
        ID:          userId,
        Title:       request.FormValue("title"),
        CurrentDate: request.FormValue("currentDate"),
        EventDate:   request.FormValue("eventDate"),
    }

    _, err := collection.InsertOne(context.TODO(), document)

    if err != nil {
        fmt.Println("Error adding document", err)
    }
    fmt.Println("Inserted a Event with Id: ", document.ID)

}

func connectToDB() {
    connectionString := "this is confidencial"
    clientOptions := options.Client().ApplyURI(connectionString)

    client, DBError = mongo.Connect(context.TODO(), clientOptions)
    if DBError != nil {
        fmt.Println("Error connecting to the DB", DBError)
        return
    }
}

func main() {
    connectToDB()
    http.HandleFunc("/", mainPage)
    http.HandleFunc("/createNewEvent", newEventPage)
    http.HandleFunc("/server-side/output.css", serveCSS)
    http.ListenAndServe(":8080", nil)
}

排查过程

  • 最初尝试为Event结构体添加bson标签,问题未解决。
  • 添加调试代码后,出现错误:http: invalid Read on closed Body。

解决方案

调整newEventPage函数的逻辑顺序,将POST请求的判断放在http.ServeFile之前,修改后的函数代码如下:

func newEventPage(w http.ResponseWriter, r *http.Request) {
    if r.Method == http.MethodPost {
        handleFormSubmit(r)
    }
    filepath := filepath.Join("client-side", "html", "createNewEvent.html")
    http.ServeFile(w, r, filepath)
}

最终效果

调整后,数据库文档已能正确存储表单数据(currentDate为空符合预期)。

内容的提问来源于stack exchange,提问作者Vebjørn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 07:16:08