curl 请求 gzip 后得到二进制内容:Accept-Encoding 不会自动解压
手工声明 Accept-Encoding 只请求压缩;启用 --compressed 解码响应,并区分 HTTP 内容编码与压缩包下载。
curl 添加 -H 'Accept-Encoding: gzip' 后,网页正文变成乱码或二进制,保存的文件也不是预期 HTML。如果响应确实有 Content-Encoding: gzip,先区分“要求服务器压缩”和“让 curl 解压输出”两件事。
本文讨论 HTTP 响应的内容编码,不是直接下载 .gz 压缩包。后者本来就是下载目标,不应仅因为文件内容是二进制就解压。
自己加请求头,不会打开 curl 的解码功能
下面的命令示例只声明客户端接受 gzip:
curl -H 'Accept-Encoding: gzip' \
--output response.bin 'https://example.com/page'
域名和路径需要替换;目标文件应使用新的名称,避免覆盖已有资料。服务器按该请求头返回 gzip 内容时,curl 不会仅凭手工设置的头自动启用响应解压。
想拿到正常文本,通常使用 --compressed:
curl --compressed --output page.html \
'https://example.com/page'
它会请求 curl 当前构建支持的内容编码,并在收到相应 Content-Encoding 后解压正文。支持 gzip、Brotli 或其他格式取决于构建配置,不能假定每台机器支持同一组编码。
需要固定 Accept-Encoding 时,可以同时启用解压
有些排查必须固定请求头,不能让 curl 自动选择整组编码。可以保留自己的头,再启用解压功能:
curl --compressed -H 'Accept-Encoding: gzip' \
--dump-header headers.txt --output page.html \
'https://example.com/page'
这里 headers.txt 和 page.html 是示例输出文件。头文件仍记录服务器原始响应头,所以可能保留 Content-Encoding: gzip 和压缩后的 Content-Length;正文文件已被解压,不能用这个 Content-Length 直接要求解压后文件大小一致。
把响应头用 --dump-header 单独保存,也便于核对它实际送出的内容编码。不要把 -i 打印出的 HTTP 头与压缩流混在一起后,再把整段内容交给 gzip 工具。
开启 --compressed 后仍有问题
先看响应头是否真的包含 Content-Encoding: gzip。如果只是下载接口返回了一个 gzip 文件,并没有这个内容编码头,curl 不应擅自解压下载物。若服务发出了错误的编码头,或把内容压缩两次,需要检查服务端及代理的编码设置。
curl 报不支持的内容编码时,检查当前构建支持什么,或让服务器返回受支持的编码;不要无条件追加多次解压来掩盖协商错误。保存出来的内容若是登录页或错误页,则再核对 HTTP 状态、认证和跳转,解压不会使它变成目标业务响应。
验证结果时检查状态、响应编码和实际正文:页面应是可读取的目标文本;压缩包下载则应保持预期的文件格式。仅让终端不再显示二进制警告,不能证明内容正确。


