在一个项目中,我编写了一套代理服务,在测试中我想访问我的网站,我可以将内容转发到 https://www.qq.com/,但是我发现读取这个服务的返回值的时候,发现读取到内容并非完整的 html ,而是看起来像是乱码的内容。
经过一番仔细排查才发现,原来是因为腾讯的服务器是将返回的内容进行 gzip 压缩,我这边将数据进行 gzip 解压,获取关键信息然后进行转发,但是通过 curl 还是无法获取到准确的数据,会报错 curl: (61) Error while processing content unencoding: invalid distance too far back
,通过排查发现 curl 添加了 --compress 选项,如果有这个选项,curl 会携带 accept-encoding: deflate, gzip
,去掉此选项就能准确返回数据。后面在代理服务增加了对 deflate 的支持,发现 curl 返回成功。
既然文章主题是 web 压缩算法,其实比较流行的算法有 gzip 和 deflate,翻阅 MDN 文档,可以看到还有几个选项,以及可以一次性提供多个选项,让服务器决定使用哪一套算法。
Content-Encoding: gzip
Content-Encoding: compress
Content-Encoding: deflate
Content-Encoding: br
// Multiple, in the order in which they were applied
Content-Encoding: deflate, gzip
gzip 和 deflate 底层差不多使用的是同一套算法,可以从 golang 的源码中得知,并且 gzip 使用了 crc32 作为校验码。
br 算法全称是 brotli,golang 标准库中没有对此算法的实现,谷歌官方有个基于 cgo 的 brotli 算法实现 google/brotli,这套算法压缩率和时间相比 gzip 相比都比较优越,不过对于浏览器支持方面比较欠缺,并且我发现 cloudflare 中已经支持 br 算法,所以套用 cf 的梯子应该可以传输更少的数据提高传输效率。
网友评论