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

使用Go开发收据Web应用时JSON解析失败的技术求助

解决Go Web应用中JSON解析错误:invalid character 'r' looking for beginning of value

问题根源

你遇到的错误是因为前端表单默认提交的是application/x-www-form-urlencoded格式,请求体内容是类似receipt={你的JSON内容}的键值对,而非纯JSON字符串。后端用json.NewDecoder(r.Body).Decode(&receipt)直接解析整个请求体,自然会因为开头的receipt=字符导致JSON解析失败。

修复方案

提供两种可行的修复方式,根据你的需求选择:

方案1:后端适配表单提交(无需修改前端)

修改receiptHandler中的POST处理逻辑,先解析表单数据,提取出textarea中的JSON字符串后再进行解析:

func receiptHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method == "POST" {
        // 解析表单数据
        err := r.ParseForm()
        if err != nil {
            http.Error(w, "表单解析失败", http.StatusBadRequest)
            return
        }
        // 获取输入的JSON内容
        receiptJSON := r.FormValue("receipt")
        if receiptJSON == "" {
            http.Error(w, "请输入收据JSON", http.StatusBadRequest)
            return
        }

        var receipt Receipt
        // 将JSON字符串解析到结构体
        err = json.Unmarshal([]byte(receiptJSON), &receipt)
        if err != nil {
            http.Error(w, "JSON格式错误:"+err.Error(), http.StatusBadRequest)
            return
        }

        j, _ := json.MarshalIndent(receipt, "", "    ")
        fmt.Println(string(j))

        result := processReceipt(receipt)

        tmpl := template.Must(template.ParseFiles("result.html"))
        tmpl.Execute(w, result)
    } else {
        tmpl := template.Must(template.ParseFiles("index.html"))
        tmpl.Execute(w, nil)
    }
}

方案2:前端改为提交纯JSON(RESTful风格)

保留后端原有的JSON解析逻辑,修改前端用JavaScript发送JSON格式请求:

<!DOCTYPE html>
<html>
<head>
    <title>Receipt Processor</title>
</head>
<body>
    <h1>Receipt Processor</h1>
    <textarea id="receipt" rows="10" cols="50"></textarea><br><br>
    <button onclick="submitReceipt()">Process Receipt</button>

    <script>
        function submitReceipt() {
            const receiptJSON = document.getElementById('receipt').value;
            fetch('/', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: receiptJSON,
            })
            .then(response => {
                if (!response.ok) throw new Error('请求失败');
                return response.text();
            })
            .then(html => {
                document.body.innerHTML = html;
            })
            .catch(error => {
                alert('错误:' + error.message);
            });
        }
    </script>
</body>
</html>

这种方式下,后端原有的json.NewDecoder代码可以正常工作,无需修改。

额外优化建议

  1. 错误提示优化:解析JSON时可以返回更友好的错误信息,帮助用户定位格式问题
  2. 随机ID生成优化:当前用rand.Intn生成ID,建议替换为crypto/rand包生成更安全、不易重复的随机ID
  3. 字段类型优化:Total和Price字段可以改用decimal.Decimal(第三方库)或float64存储,减少字符串转浮点数的重复操作,避免精度丢失

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 08:34:57