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

Go区块链API GET请求报错:invalid character 'þ'寻找值起始位置

问题根源与解决方案

核心问题定位

你遇到的invalid character 'þ' looking for beginning of value错误,本质是响应内容包含无效UTF-8字符或非JSON格式数据,由以下代码问题导致:

  1. 格式化符误用:CalculateHash函数中对字符串类型的PropertyAddress使用了浮点数格式符%f,导致生成的字符串包含无效字节;
  2. 编码方式混用:Contract.ToBytes()用Gob编码存储数据,但后续代码尝试用JSON解析这些二进制字节,解析失败后产生错误响应;
  3. 区块链逻辑错误:AddBlock方法错误复用前一个区块的Contract数据创建新块,而非使用传入的合同数据,进一步导致数据混乱。

分步修复方案

1. 修复CalculateHash的格式化错误

修改blockchain/Blockchain.go中的CalculateHash函数,将PropertyAddress的格式符从%f改为字符串格式符%s:

func CalculateHash(data Contract, prevHash string, timestamp time.Time) string {
    record := fmt.Sprintf("%s%d%d%s%s%s%s%s%f%f%f%t%s%s",
        data.ID,
        data.StartTime,
        data.ContractDuration,
        data.EndTime,
        data.CurrentStage,
        data.PropertyHash,
        data.PropertyID,
        data.PropertyAddress, // 此处将%f改为%s
        data.RentAmount,
        data.DepositAmount,
        data.DepositDeductions,
        data.ContractSigned,
        prevHash,
        timestamp.Format(time.RFC3339),
    )
    h := sha256.New()
    h.Write([]byte(record))
    hashed := h.Sum(nil)
    return hex.EncodeToString(hashed)
}

2. 统一数据编码方式

将Contract.ToBytes()改为JSON编码,与后续解析逻辑统一:

func (c *Contract) ToBytes() []byte {
    data, err := json.Marshal(c)
    if err != nil {
        log.Fatalf("failed to encode contract: %v", err)
    }
    return data
}

3. 修正AddBlock的逻辑错误

当前AddBlock错误复用前一个区块的数据,改为使用传入的合同数据创建新块:

func (bc *Blockchain) AddBlock(contract Contract, prevHash string) {
    newBlock := CreateBlock(len(bc.Blocks), contract, prevHash)
    bc.Blocks = append(bc.Blocks, newBlock)
}

4. 确保响应数据可正确序列化

检查contracts.ListContracts()函数,确保它从区块链中正确解码Contract数据:

// contracts包示例实现
func ListContracts() ([]blockchain.Contract, error) {
    bc := blockchain.NewBlockchain()
    var contractList []blockchain.Contract
    for _, block := range bc.Blocks {
        var contract blockchain.Contract
        err := json.Unmarshal(block.Data, &contract)
        if err != nil {
            return nil, err
        }
        contractList = append(contractList, contract)
    }
    return contractList, nil
}

5. 优化响应日志中间件

避免将二进制数据直接转为字符串,防止引入无效字符:

// 导入必要包:"encoding/base64"、"unicode/utf8"
func (rl *responseLogger) Write(body []byte) (int, error) {
    if utf8.Valid(body) {
        rl.body = string(body)
    } else {
        rl.body = base64.StdEncoding.EncodeToString(body)
    }
    return rl.ResponseWriter.Write(body)
}

验证修复

重启服务器后,再次发送GET localhost:8080/contracts请求,响应应返回标准JSON格式,错误消失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 22:24:55