接口开了 gzip,前端收到 JSON 解析到一半报 Unexpected end of JSON input。抓包看响应体 12KB,Content-Length 写的是 38KB。第一次遇到会往复杂处想,其实漏掉的多是个小前提。
curl -sI -H 'Accept-Encoding: gzip' https://api.example.com/v1/orders | grep -i -E 'content-length|content-encoding|transfer-encoding'
应用先算好未压缩的长度写进 Content-Length,后面又交给压缩中间件输出,头没有跟着改。客户端按 Content-Length 读够 38KB 才算完,实际只有 12KB,读到一半就断了。这一点先确认清楚,后面就不用反复试。
「gzip 截断」相关的验证我通常做两遍,改完一次、隔天再看一次,确认不是临时生效。临时改动用注释写上日期和原因,过两周自己都记不清为什么这么写。
动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。一次只改一处,改完立刻验证,几个改动叠在一起,出问题就说不清是谁导致的。
具体做法是,开了压缩就让服务器用 chunked 传输 不要手工写 Content-Length;确认压缩中间件在写响应头之前执行 顺序反了就会留下旧长度;反向代理层关掉对已压缩响应的二次压缩;用 curl 带 Accept-Encoding 检查响应头组合。
改完照着核一遍,响应头里不再同时出现 Content-Length 和 Content-Encoding 前端能完整解析 JSON。
