var buf bytes.Buffer enc := json.NewEncoder(&buf) enc.SetEscapeHTML(false) enc.Encode(data)
接口返回 2.4KB 的 URL 里 & 变成 \u0026,前端拼签名时按原字符串算,和网关算出的结果不一致,验签一直失败。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。
原因不复杂,encoding/json 默认开启 HTML 转义,把 < > & 换成 Unicode 转义序列,输出仍是合法 JSON,但字节层面已经不同。前端如果拿原始响应体做签名就会踩到。
围绕「Go JSON HTML 转义」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。改动写完就同步给同事,下一个人踩同一个坑,成本还是你的。
验证用真实数据走一遍,测试数据太干净,边界情况根本碰不到。能分两步做的操作就别合成一步,中间看一眼返回值,出问题好判断。
处理上按这个顺序:用 Encoder 并调用 SetEscapeHTML(false);或统一在签名前先解析 JSON 再取字段;确认网关和客户端用的是同一份序列化结果;不要用字符串拼接响应体做签名原文。
改完只确认一件事:响应体里 & 原样输出 前后端签名结果一致。
