使用 http 编码时,启用响应压缩(仅)的一种好方法是使用 dynamic compression built-in to IIS7 and higher。
但我不明白客户端如何知道压缩请求和解压缩响应?
以下是对 HTTP 开箱即用功能的描述,这些功能可以与 WCF HTTP(S) 编码一起使用。除此之外,WCF 4.5 还提供了gzip and deflatecompression of its binary encoding。
压缩响应是 HTTP 标准的一部分。在其请求中,客户端通过以下标头向服务器发送其支持的压缩方法(gzip、deflate、...)的信号:
Accept-Encoding: gzip, deflate
服务器可以自行决定以无限的智慧和神秘的方式忽略该标头并发送未压缩的响应,或者它可以选择客户端提供的任何一种算法,例如,回答如下标头并压缩响应正文。
Content-Encoding: gzip
为了让事情变得更复杂,服务器可能还会设置以下标头:
Transfer-Encoding: chunked
这允许服务器省略其他强制性的 Content-Length 标头,作为一般的 HTTP 标头,必须在 HTTP 正文之前。 (设置chunked 编码affects the way the body gets encoded。)所以现在它可以即时压缩响应主体,即在压缩时吐出字节,而无需等待整个主体的压缩完成,只需能够确定压缩结果的内容长度。这可以在服务器端节省大量内存。 (然而,客户端现在对压缩响应的总大小一无所知,直到它完成接收整个响应,这使得它的解压效率略低)
但是请注意,根据 http 合著者 Roy Fielding 的说法,使用 Accept-Encoding 和 Content-Encoding(正如我刚才所描述的)来透明地压缩响应实际上是 a stupid idea,并且应该是而是使用请求中的以下标头:
TE: gzip, deflate
如果服务器选择执行压缩,则会在其响应中添加以下标头:
Transfer-Encoding: gzip, chunked
和以前一样,如果服务器想要省略 Content-Length,chunked 是必需的。
否则,TE/Transfer-Encoding 组合在语法上与Accept-Encoding/Content-Encoding 组合相同,但含义不同,可以从this longish discussion 中收集到。
问题的要点:TE/Transfer-Encoding 使压缩成为传输细节,而 Accept-Encoding/Content-Encoding 将压缩版本表示为实际数据(entity em> 在 HTTP 用语中),对于后者的请求缓存、代理等有许多不幸的后果。
但是,TE/Transfer-Encoding 的船很久以前就开始航行了,我们被困在 AE/CE 组合上,它得到了大多数客户端和服务器的支持,实际上更接近于 TE/TE
当涉及到 HTTP 中的压缩请求时,它们在实践中很少使用,并且客户端没有标准的方法来确定服务器是否支持它。要么你告诉客户端带外(例如硬编码)服务器理解压缩请求(和configure the server appropriately)。或者您让您的客户端主动尝试压缩一次,如果它产生400 Bad Request(至少这是 IIS 7.5 会返回的结果),您将退回到非压缩请求。