我编写了一个 bash 脚本,它使用 curl 从网站获取输出,并对 html 输出进行一系列字符串操作。问题是当我对一个返回其输出 gzip 的站点运行它时。在浏览器中访问该站点可以正常工作。
当我手动运行 curl 时,我得到 gzipped 输出:
$ curl "http://example.com"
这是该特定站点的标题:
HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html; charset=utf-8
X-Powered-By: PHP/5.2.17
Last-Modified: Sat, 03 Dec 2011 00:07:57 GMT
ETag: "6c38e1154f32dbd9ba211db8ad189b27"
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Cache-Control: must-revalidate
Content-Encoding: gzip
Content-Length: 7796
Date: Sat, 03 Dec 2011 00:46:22 GMT
X-Varnish: 1509870407 1509810501
Age: 504
Via: 1.1 varnish
Connection: keep-alive
X-Cache-Svr: p2137050.pubip.peer1.net
X-Cache: HIT
X-Cache-Hits: 425
我知道返回的数据是 gzip 压缩的,因为这会返回 html,如预期的那样:
$ curl "http://example.com" | gunzip
我不想通过 gunzip 管道输出,因为脚本在其他站点上按原样工作,并且通过 gzip 管道会破坏该功能。
我试过的
更改用户代理(我尝试了浏览器发送的相同字符串,“Mozilla/4.0”等) man curl google search search stackoverflow
一切都是空的
有任何想法吗?
curl 7.54.0 (x86_64-apple-darwin17.0) libcurl/7.54.0 LibreSSL/2.0.20 zlib/1.2.11 nghttp2/1.24.0
) - 通过从 Accept-Encoding
中删除 br
解决了这个问题。见stackoverflow.com/questions/18983719/…
curl -sSv https://stackoverflow.com/ |& rg -i 'gzip|accept'
,并与 --compressed
一起尝试。除非 curl
通过 Accept-Encoding
,否则服务器不会压缩响应。
如果您设置 --compressed
标志,curl
将自动解压缩响应:
curl --compressed "http://example.com"
--compressed (HTTP) 使用 libcurl 支持的算法之一请求压缩响应,并保存未压缩的文档。如果使用了这个选项并且服务器发送了一个不支持的编码,curl 会报错。
gzip 很可能受支持,但您可以通过运行 curl -V
并在“功能”行中的某处查找 libz 来检查:
$ curl -V
...
Protocols: ...
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz
请注意,这里确实是有问题的网站。如果 curl
未传递 Accept-Encoding: gzip
请求标头,则服务器不应发送压缩响应。
在相关的错误报告 Raw compressed output when not using --compressed but server returns gzip data #2836 中,开发人员说:
服务器不应该发送 content-encoding: gzip 没有客户端发出信号可以接受。
此外,当您不将 --compressed 与 curl 一起使用时,您会告诉命令行工具您宁愿存储确切的流(压缩与否)。我在这里没有看到卷曲错误......
因此,如果服务器可以发送 gzip 压缩的内容,请使用 --compressed
让 curl 自动解压缩它。
curl
确实 通过省略 Accept-Encoding
标头表示它是可以接受的。该标准规定,在这种情况下,“如果请求中没有 Accept-Encoding 字段,则用户代理认为任何内容编码都是可接受的。” (我认为,要表示不接受任何编码,需要 Accept-Encoding: identity
或 `*;q=0,或空标题。)
Accept-Encoding: deflate, gzip
是不够的 - 即使服务器返回带有Content-Encoding: gzip
的 gzip 响应,curl 也不会自动解压缩它。--compressed
标志是必需的。