1. 简介
本节为非规范性内容。
本规范中定义的 API 用于对数据流进行压缩和解压。它们支持 "deflate"、"deflate-raw" 和 "gzip" 作为压缩算法,这些算法被网页开发者广泛使用。
2. 基础设施
本规范依赖于 Infra。[INFRA]
一个 chunk 是一段数据。对于 CompressionStream 和 DecompressionStream,输出 chunk 类型为 Uint8Array。它们接受任何 BufferSource
类型作为输入。
一个 stream 表示有序的 chunk 序列。ReadableStream
和 WritableStream
的术语定义在 Streams。[STREAMS]
压缩上下文 是压缩或解压算法维护的内部状态。压缩上下文 的内容取决于所用的格式、算法和实现。从本规范的角度来说,它是一个不透明对象。压缩上下文 初始处于起始状态,等待输入的第一个字节。
3. 支持的格式
deflate
-
“ZLIB 压缩数据格式”[RFC1950]
注:为了与 HTTP 内容编码保持一致,该格式称为 “deflate”。参见 [RFC7230] 第4.2.2节。
deflate-raw
-
“DEFLATE 算法”[RFC1951]
gzip
-
“GZIP 文件格式”[RFC1952]
-
实现必须遵循 [RFC1952] 第2.3.1.2节所述的“兼容性”。
-
CompressionStream 不得创建 [RFC1952] 中描述为无效的字段值,DecompressionStream 处理此类值时应报错。
-
CM
(压缩方法)字段的唯一有效值为 8。 -
DecompressionStream 必须忽略
FTEXT
标志。 -
若
FHCRC
字段存在且不正确,则会报错。 -
DecompressionStream 必须忽略
FEXTRA
、FNAME
和FCOMMENT
字段的内容,仅需验证其正确结束。 -
DecompressionStream 必须忽略
MTIME
、XFL
和OS
字段的内容。 -
若
CRC32
或ISIZE
与解压后的数据不匹配,则会报错。 -
gzip
流只能包含一个“成员”。 -
若“成员”结束后还有额外输入数据,则会报错。
-
4. 接口 CompressionStream
enum {
CompressionFormat ,
"deflate" ,
"deflate-raw" , }; [Exposed=*]
"gzip" interface {
CompressionStream constructor (CompressionFormat ); };
format CompressionStream includes GenericTransformStream ;
CompressionStream
拥有一个 格式 和一个
压缩上下文
上下文。
new CompressionStream(format)
的步骤如下:
-
如果 format 在
CompressionStream
中不支持,则抛出TypeError
。 -
令 transformAlgorithm 为一个接受 chunk 参数的算法,并使用 压缩并入队一个块 算法,传入 this 和 chunk。
-
将 this 的 transform 设为 新建的
TransformStream
。 -
设置 this 的 transform,其 transformAlgorithm 设为 transformAlgorithm,flushAlgorithm 设为 flushAlgorithm。
CompressionStream
对象 cs 与 chunk,执行以下步骤:
-
如果 chunk 不是
BufferSource
类型,则抛出TypeError
。 -
如果 buffer 为空,则返回。
-
令 arrays 为将 buffer 拆分为一个或多个非空片段并转换为
Uint8Array
的结果。 -
对每个
Uint8Array
array 属于 arrays,入队 array 到 cs 的 transform 中。
ReadableStream
对象的数据结束,给定 CompressionStream
对象 cs,执行下列步骤:
-
如果 buffer 为空,则返回。
-
令 arrays 为将 buffer 拆分为一个或多个非空片段并转换为
Uint8Array
的结果。 -
对每个
Uint8Array
array 属于 arrays,入队 array 到 cs 的 transform 中。
5. 接口 DecompressionStream
[Exposed=*]interface {
DecompressionStream constructor (CompressionFormat ); };
format DecompressionStream includes GenericTransformStream ;
DecompressionStream
拥有一个 格式 和一个
压缩上下文
上下文。
new DecompressionStream(format)
的步骤如下:
-
如果 format 在
DecompressionStream
中不支持,则抛出TypeError
。 -
令 transformAlgorithm 为一个接受 chunk 参数的算法,并使用 解压并入队一个块 算法,传入 this 和 chunk。
-
将 this 的 transform 设为 新建的
TransformStream
。 -
设置 this 的 transform,其 transformAlgorithm 设为 transformAlgorithm,flushAlgorithm 设为 flushAlgorithm。
DecompressionStream
对象 ds 与 chunk,执行以下步骤:
-
如果 chunk 不是
BufferSource
类型,则抛出TypeError
。 -
令 buffer 为使用 ds 的 格式 和 上下文 解压 chunk 的结果。如果产生错误,则抛出
TypeError
。 -
如果 buffer 为空,则返回。
-
令 arrays 为将 buffer 拆分为一个或多个非空片段并转换为
Uint8Array
的结果。 -
对每个
Uint8Array
array 属于 arrays,入队 array 到 ds 的 transform 中。
ReadableStream
对象的数据结束,给定 DecompressionStream
对象 ds,执行下列步骤:
-
如果压缩输入的结尾尚未到达,则抛出
TypeError
。 -
如果 buffer 为空,则返回。
-
令 arrays 为将 buffer 拆分为一个或多个非空片段并转换为
Uint8Array
的结果。 -
对每个
Uint8Array
array 属于 arrays,入队 array 到 ds 的 transform 中。
6. 隐私与安全注意事项
该 API 不会为 Web 平台带来任何新的权限。
但是,网页开发者需要注意攻击者可能获得数据长度的情况。如果发生这种情况,攻击者可能能够猜测数据内容。
7. 示例
7.1. Gzip 压缩流
7.2. Deflate 压缩 ArrayBuffer 到 Uint8Array
async function compressArrayBuffer( input) { const cs= new CompressionStream( 'deflate' ); const writer= cs. writable. getWriter(); writer. write( input); writer. close(); const output= []; let totalSize= 0 ; for ( const chunkof cs. readable) { output. push( value); totalSize+= value. byteLength; } const concatenated= new Uint8Array( totalSize); let offset= 0 ; for ( const arrayof output) { concatenated. set( array, offset); offset+= array. byteLength; } return concatenated; }
7.3. Gzip 解压 Blob 到 Blob
function decompressBlob( blob) { const ds= new DecompressionStream( 'gzip' ); const decompressionStream= blob. stream(). pipeThrough( ds); return new Response( decompressionStream). blob(); }
致谢
感谢 Canon Mukai、Domenic Denicola 和 Yutaka Hirano 的支持。本标准由 Adam Rice (Google, ricea@chromium.org) 编写。
知识产权
版权所有 © WHATWG(Apple、Google、Mozilla、Microsoft)。本作品采用 知识共享署名 4.0 国际许可证 许可。在其部分内容被纳入源代码时,该部分在源代码中则采用 BSD 3-Clause 许可证 许可。
这是现行标准。希望查阅专利审查版本的请查看 现行标准审查草案。