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

JS客户端向Golang服务器POST数据失败,请求排查问题原因

客户端POST请求返回无效请求的问题分析

问题场景

搭建了一套以JS/HTML为客户端、Golang为服务端、PostgreSQL为数据库的REST API授权服务:

  • Postman发送POST请求时,能正常获得预期响应,数据也能存入数据库
  • JS/HTML客户端发送请求时,返回结果为无效请求:{"message":"Invalid request","status":false}

服务端核心代码

var CreateAccount = func(w http.ResponseWriter, r *http.Request) {
    account := &models.Account{}
    err := json.NewDecoder(r.Body).Decode(account) // 解析请求体为结构体,出错则返回无效请求
    if err != nil {
        utils.Respond(w, utils.Message(false, "Invalid request"))
        return
    }

    resp := account.Create() // 创建账户
    utils.Respond(w, resp)
}

客户端代码

JavaScript部分

'use strict'

const form = document.getElementById('form');
const url = "http://localhost:8080/api/user/login";


const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");

form.addEventListener('submit', (e) => {
    e.preventDefault();

    const data = new FormData(form);

    let preparedData = JSON.stringify([...data].flat());
    console.log(preparedData)

    fetch(url, {
        method: "POST",
        body: data,
    })
        .then(response => response.text())
        .then(result => console.log(result))
        .catch(error => console.log('error', error));
});

HTML部分

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel='stylesheet' href='style.css'>
    <title>Real Estate Moskow Hack</title>
</head>
<body>
    <header class="header">

    </header>
    <!-- HEADER END -->
    
    <main class="main">

        <form action="http://localhost:8080/api/user/login" method="POST" id="form">

            <input class="email" type="text" name="email" placeholder="Введите email">
            <input class="password" type="password" name="password" id="password" placeholder="Введите пароль">
            <button class="button" type="submit">send data</button>
        </form>
        
    </main>
    <!-- MAIN END -->
    
    <footer class="footer">

    </footer>
    <script src="script.js"></script>
</body>
</html>

问题定位与原因

问题出在客户端,核心原因有两点:

  1. 未传递正确的请求头
    服务端依赖json.NewDecoder解析JSON格式请求体,需要请求头包含Content-Type: application/json。客户端虽然创建了myHeaders配置该头,但没有在fetch请求中传入这个配置项,导致请求头默认是multipart/form-data,服务端无法解析。

  2. 请求体格式不匹配
    客户端实际发送的是FormData对象,而非服务端期望的JSON格式。即便定义了preparedData做JSON序列化,但最终fetch的body参数传的是原始data(FormData),而且[...data].flat()的转换方式会把表单的键值对转为扁平数组(比如["email", "xxx", "password", "yyy"]),不是服务端需要的键值对象结构({"email":"xxx", "password":"yyy"})。

修正后的客户端JavaScript代码

'use strict'

const form = document.getElementById('form');
const url = "http://localhost:8080/api/user/login";

form.addEventListener('submit', (e) => {
    e.preventDefault();

    // 将FormData转换为标准键值对象
    const formData = new FormData(form);
    const requestData = Object.fromEntries(formData);
    
    fetch(url, {
        method: "POST",
        // 传递正确的Content-Type头
        headers: {
            "Content-Type": "application/json"
        },
        // 发送JSON格式的请求体
        body: JSON.stringify(requestData)
    })
        .then(response => response.json())
        .then(result => console.log(result))
        .catch(error => console.log('error', error));
});

内容的提问来源于stack exchange,提问作者Victor Bej

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 14:41:26