本文共 1752 字,大约阅读时间需要 5 分钟。
HTTP 协议中的 Accept-Encoding/Content-Encoding 机制。它可以很好地用于文本类响应正文的压缩,减少网络数据传输,所以一直被广泛使用。但 HTTP 请求的发起方浏览器,无法事先知晓要访问的服务端是否支持解压,所以现阶段的浏览器没有压缩请求正文。
有一些通讯协议基于 HTTP 做了扩展,他们的客户端和服务端是专用的,完全可以针对请求正文进行压缩,例如 WebDAV 客户端就是这么做的。
HTTP中各压缩算法
实际的 Web 项目中,会存在请求正文非常大的场景,例如发表长篇博客,上报用于调试的网络数据等等。这些数据如果能在本地压缩后再提交,就可以节省大量流量、减少传输时间。本文介绍如何对 HTTP 请求正文进行压缩,包含如何在服务端解压、如何在客户端压缩两个部分。
开始之前,先来介绍本文涉及的三种数据压缩格式:DEFLATE,是一种使用 Lempel-Ziv 压缩算法(LZ77)和哈夫曼编码的压缩格式。详见 RFC 1951;
ZLIB,是一种使用 DEFLATE 的压缩格式,对应 HTTP 中的 Content-Encoding: deflate。详见 RFC 1950;
GZIP,也是一种使用 DEFLATE 的压缩格式,对应 HTTP 中的 Content-Encoding: gzip。详见 RFC 1952;
Content-Encoding 中的 deflate,实际上是 ZLIB。为了清晰,本文将 DEFLATE 称之为 RAW DEFLATE,ZLIB 和 GZIP 都是 RAW DEFLATE 的不同 Wrapper。
解压请求正文
服务端收到请求正文后,需要分析请求头中的 Content-Encoding 字段,才能知道正文采用了哪种压缩格式。本文规定用 gzip、deflate 和 deflate-raw 分别表示请求正文采用 GZIP、ZLIB 和 RAW DEFLATE 压缩格式。
PHP应用实现
PHP 也内置了处理这些压缩格式的函数,以下是实例代码:<?php
$encoding = isset($_SERVER['HTTP_CONTENT_ENCODING'])?$_SERVER['HTTP_CONTENT_ENCODING']:"";
$row_post_data = file_get_contents("php://input");
/**
* gzcompress => zlib deflate
* gzdecode => gzip gzip
* gzdeflate => DEFLATE deflate-raw
*/
switch($encoding) {
case 'gzip':
$post_data = gzdecode($row_post_data);
break;
case 'deflate':
//$post_data = gzinflate(substr($row_post_data, 2, -4)) . PHP_EOL . PHP_EOL;
//$post_data = gzinflate(substr($row_post_data, 10, -8)) . PHP_EOL . PHP_EOL;
$post_data = gzuncompress($row_post_data);
break;
case 'deflate-raw':
$post_data = gzinflate($row_post_data);
break;
default:
$post_data = $row_post_data;
break;
}
可以看到,ZLIB 格式的压缩数据去掉头尾,就是 RAW DEFLATE,可以直接用 gzinflate 解压。跟前面一样,如果采用 PHP 解压方案,也应该在框架层统一处理。PHP还提供了
gzuncompress 也是官方提供的一个解压缩函数,原文如下:
This function compresses the given string using the ZLIB data format.
用于zlib格式,不过命名方式略坑爹。[尚无相关文章]
转载地址:https://blog.csdn.net/weixin_33960567/article/details/115753129 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!