1. 简介
本节为非规范性内容。
本规范中定义的 API 用于对数据流进行压缩和解压。它们支持 "deflate"、"deflate-raw" 和 "gzip" 作为压缩算法,这些算法被网页开发者广泛使用。
2. 基础设施
本规范依赖于 Infra。[INFRA]
一个 chunk 是一段数据。对于 CompressionStream 和 DecompressionStream,输出 chunk 类型为 Uint8Array。它们接受任何 BufferSource
类型作为输入。
一个 stream 表示有序的 chunk 序列。ReadableStream
和 WritableStream
的术语定义在 Streams。[STREAMS]
压缩上下文 是压缩或解压算法维护的内部状态。压缩上下文 的内容取决于所用的格式、算法和实现。从本规范的角度来说,它是一个不透明对象。压缩上下文 初始处于起始状态,等待输入的第一个字节。
3. 支持的格式
brotli-
"Brotli 压缩数据格式" [RFC7932]
-
实现必须如 [RFC7932] 第 1.4 节所述“兼容”。
-
由
CompressionStream生成的块不得不符合 [RFC7932] 标准,否则对DecompressionStream来说是错误。
-
deflate-
"ZLIB 压缩数据格式" [RFC1950]
注意:为与 HTTP 内容编码保持一致,该格式称为 "deflate"。参见 [RFC7230] 第 4.2.2 节。
-
实现必须如 [RFC1950] 第 2.3 节所述“兼容”。
-
[RFC1950] 描述为无效的字段值不得由
CompressionStream生成, 并且对DecompressionStream来说是错误。 -
CMF字段中的CM(压缩方法)部分唯一有效的值为 8。 -
这些 API 不支持
FDICT标志,如果设置则会使流出错。 -
DecompressionStream会忽略FLEVEL标志。 -
若
ADLER32校验和不正确,则对DecompressionStream来说是错误。 -
如果在
ADLER32校验和之后还有额外输入数据,则为错误。
-
deflate-raw-
"DEFLATE 算法" [RFC1951]
-
实现必须如 [RFC1951] 第 1.4 节所述“兼容”。
-
由
CompressionStream生成的块不得不符合 [RFC1951] 标准,否则对DecompressionStream来说是错误。 -
如果在
BFINAL标志指示的最后一个块之后还有额外输入数据,则为错误。
-
gzip-
"GZIP 文件格式" [RFC1952]
-
实现必须如 [RFC1952] 第 2.3.1.2 节所述“兼容”。
-
[RFC1952] 描述为无效的字段值不得由
CompressionStream生成, 并且对DecompressionStream来说是错误。 -
CM(压缩方法)字段的唯一有效值为 8。 -
DecompressionStream必须忽略FTEXT标志。 -
如果
FHCRC字段存在且错误,则为错误。 -
任何
FEXTRA、FNAME和FCOMMENT字段内容 除了要验证正确结束外,都必须由DecompressionStream忽略。 -
MTIME、XFL和OS字段内容 必须由DecompressionStream忽略。 -
如果
CRC32或ISIZE与解压后的数据不匹配,则为错误。 -
一个
gzip流只可包含一个“成员”。 -
如果在“成员”结尾后还有额外输入数据,则为错误。
-
4. 接口 CompressionStream
enum {CompressionFormat ,"brotli" ,"deflate" ,"deflate-raw" , }; [Exposed=*]"gzip" interface {CompressionStream constructor (CompressionFormat ); };format CompressionStream includes GenericTransformStream ;
CompressionStream
具有关联的 format(格式) 和
compression
context(压缩上下文)
context(上下文)。
new CompressionStream(format)
步骤如下:
-
如果 format 在
CompressionStream中不被支持,则抛出TypeError。 -
令 transformAlgorithm 是一个接收 chunk 参数的算法, 并使用 compress and enqueue a chunk 算法, 传入 this 和 chunk 执行。
-
令 flushAlgorithm 是一个不接收参数的算法, 并使用 compress flush and enqueue 算法, 传入 this 执行。
-
将 this 的 transform 设为一个 新的
TransformStream。 -
使用 transformAlgorithm 设置为 transformAlgorithm 及 flushAlgorithm 设置为 flushAlgorithm 初始化/设置 this 的 transform。
CompressionStream
对象 cs 和一个 chunk,执行以下步骤:
-
如果 chunk 不是
BufferSource类型,则抛出TypeError。 -
如果 buffer 为空,则返回。
-
令 arrays 为将 buffer 拆分为一个或多个非空片段并转换为
Uint8Array的结果。 -
对于 arrays 中的每一个
Uint8Arrayarray, 在 cs 的 transform 中 enqueue(入队) array。
ReadableStream
对象流末端,给定一个
CompressionStream
对象 cs,执行以下步骤:
-
如果 buffer 为空,则返回。
-
令 arrays 为将 buffer 拆分为一个或多个非空片段并转换为
Uint8Array的结果。 -
对于 arrays 中的每一个
Uint8Arrayarray, 在 cs 的 transform 中 enqueue(入队) array。
5. 接口 DecompressionStream
[Exposed=*]interface {DecompressionStream constructor (CompressionFormat ); };format DecompressionStream includes GenericTransformStream ;
DecompressionStream
具有关联的
format(格式)
和
compression
context(压缩上下文)
context(上下文)。
new DecompressionStream(format)
步骤如下:
-
如果 format 在
DecompressionStream不被支持,则抛出TypeError。 -
令 transformAlgorithm 是一个接收 chunk 参数的算法, 并用 decompress and enqueue a chunk 算法, 传入 this 和 chunk 执行。
-
令 flushAlgorithm 是一个不接收参数的算法, 并用 decompress flush and enqueue 算法, 传入 this 执行。
-
将 this 的 transform 设为一个 新的
TransformStream。 -
使用 transformAlgorithm 设置为 transformAlgorithm 及 flushAlgorithm 设置为 flushAlgorithm, 初始化/设置 this 的 transform。
DecompressionStream
对象 ds 和一个 chunk,执行以下步骤:
-
如果 chunk 不是
BufferSource类型,则抛出TypeError。 -
令 buffer 为使用 ds 的 format 和 context 解压 chunk 的结果。如果出错,则抛出
TypeError。 -
如果 buffer 为空,则返回。
-
令 arrays 为将 buffer 拆分为一个或多个非空片段并转换为
Uint8Array的结果。 -
对于 arrays 中的每一个
Uint8Arrayarray, 在 ds 的 transform 中 enqueue(入队) array。
ReadableStream
对象流末端,给定一个
DecompressionStream
对象 ds,执行以下步骤:
-
如果 buffer 不为空:
-
令 arrays 为将 buffer 拆分为一个或多个非空片段并转换为
Uint8Array的结果。 -
对于 arrays 中的每一个
Uint8Arrayarray, 在 ds 的 transform 中 enqueue(入队) array。
-
-
如果未到压缩输入结尾,则抛出
TypeError。
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 许可证 许可。
这是现行标准。希望查阅专利审查版本的请查看 现行标准审查草案。