使用Golang WASM提交表单数据的实现方法

使用Golang WASM提交表单数据的实现方法 如何使用 Go WASM 向 Web 服务器提交表单数据?

我应该使用 Fetch API 还是 XMLHttpRequest?

1 回复

更多关于使用Golang WASM提交表单数据的实现方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在 Go WASM 中,推荐使用 syscall/js 包通过 JavaScript 的 Fetch API 提交表单数据。这种方法更现代且易于使用。以下是一个完整的示例,展示如何构建并提交包含文本字段和文件的表单数据:

package main

import (
    "bytes"
    "syscall/js"
)

func main() {
    // 等待调用
    c := make(chan struct{}, 0)
    registerCallbacks()
    <-c
}

func registerCallbacks() {
    js.Global().Set("submitForm", js.FuncOf(submitForm))
}

func submitForm(this js.Value, args []js.Value) interface{} {
    // 创建 FormData 对象
    formData := js.Global().Get("FormData").New()

    // 添加文本字段
    formData.Call("append", "username", "john_doe")
    formData.Call("append", "email", "john@example.com")

    // 如果有文件需要添加(示例)
    // fileInput := js.Global().Get("document").Call("getElementById", "fileInput")
    // files := fileInput.Get("files")
    // if files.Length() > 0 {
    //     formData.Call("append", "file", files.Index(0))
    // }

    // 使用 Fetch API 提交
    promise := js.Global().Call("fetch", "/submit", js.ValueOf(map[string]interface{}{
        "method": "POST",
        "body":   formData,
        // 注意:使用 FormData 时不要设置 Content-Type
        // 浏览器会自动设置正确的 multipart/form-data 和边界
    }))

    // 处理响应
    promise.Call("then", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
        response := args[0]
        if response.Get("ok").Bool() {
            js.Global().Get("console").Call("log", "表单提交成功")
        } else {
            js.Global().Get("console").Call("log", "表单提交失败")
        }
        return nil
    }))

    promise.Call("catch", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
        js.Global().Get("console").Call("log", "请求错误:", args[0])
        return nil
    }))

    return nil
}

如果只需要提交简单的 JSON 数据,可以使用以下方法:

func submitJSON(this js.Value, args []js.Value) interface{} {
    data := map[string]interface{}{
        "username": "john_doe",
        "email":    "john@example.com",
    }
    
    jsonData := js.ValueOf(data)
    
    promise := js.Global().Call("fetch", "/submit", js.ValueOf(map[string]interface{}{
        "method": "POST",
        "headers": js.ValueOf(map[string]interface{}{
            "Content-Type": "application/json",
        }),
        "body": js.Global().Get("JSON").Call("stringify", jsonData),
    }))

    promise.Call("then", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
        return args[0].Call("json")
    })).Call("then", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
        js.Global().Get("console").Call("log", "服务器响应:", args[0])
        return nil
    }))

    return nil
}

在 HTML 中调用:

<button onclick="submitForm()">提交表单</button>

编译命令:

GOOS=js GOARCH=wasm go build -o main.wasm

使用 Fetch API 而不是 XMLHttpRequest 的主要优势包括更简洁的 Promise-based API、更好的错误处理和更现代的规范支持。XMLHttpRequest 在 Go WASM 中也可用,但代码会更冗长且维护性较差。

回到顶部