如何在浏览器中使用JavaScript的DecompressionStream解压缩gzip文件?

6

现在所有主要的浏览器都支持解压缩流 API,但是我无法弄清楚如何在浏览器中使用fetch()来解压缩gzip文件。

以下代码适用于base64字符串:

const decompress = async (url) => {
  const ds = new DecompressionStream('gzip');
  const response = await fetch(url);
  const blob_in = await response.blob();
  const stream_in = blob_in.stream().pipeThrough(ds);
  const blob_out = await new Response(stream_in).blob();
  return await blob_out.text();
};

decompress(
  'data:application/octet-stream;base64,H4sIAAAAAAAAE/NIzcnJVyjPL8pJAQBSntaLCwAAAA=='
).then((result) => {
  console.log(result);
});

然而,如果我在MacOS上使用gzip hello.txt创建一个hello.txt.gz文件(hello.txt是一个包含内容"hello world"的纯文本文件),那么上面的函数会抛出一个错误。
decompress('/hello.txt.gz').then((result) => {
  console.log(result);
});

# FireFox
Failed to read data from the ReadableStream: “TypeError: The input data is corrupted: incorrect header check”.
Uncaught (in promise) DOMException: The operation was aborted.

# Chrome
Uncaught (in promise) TypeError: Failed to fetch

# Safari
[Error] Unhandled Promise Rejection: TypeError: TypeError: Failed to Decode Data.
[Error] Unhandled Promise Rejection: TypeError: Failed to Decode Data.

编辑

Stackblitz上有一个可复制的演示。


1
"获取失败" - 首先,该文件是否可访问? - Bagus Tesa
1
"Failed to fetch" - 首先,文件是否可访问? - Bagus Tesa
2
噢,那很有趣,但是不,响应是不可行的。服务端发送的Content-Type是"text/plain",Content Encoding是"gzip",并且没有传递任何数据。不知何故,.gz扩展名让它以为它是自己的一种响应或类似的东西。将文件的扩展名改为.bin,它就能正常工作。我真的不确定为什么服务器会这样行为,也不确定这是否只是StackBlitz的问题,还是默认配置的问题。我刚在我的本地主机(几乎是裸露的Apache配置)上尝试了一下,结果运行良好,所以这可能是一个StackBlitz的问题。 - Kaiido
2
哦,那很有趣,但是不行,响应不对。服务器发送的Content-Type是"text/plain",Content Encoding是"gzip",并且没有传递任何数据。不知为何,文件的.gz扩展名让它以为这是自己的响应之类的东西。将你的文件扩展名改为.bin,就可以正常工作了。我真的不确定服务器为什么会这样行为,也不确定这是否只是一个stackblitz的问题,还是默认配置的问题。我在我的本地主机上尝试过(几乎是裸露的Apache配置),一切都正常,所以应该是stackblitz的问题。 - Kaiido
2
哦,那很有趣,但是不,响应不正确。服务器将Content-Type设置为"text/plain",Content Encoding设置为"gzip",并且没有传递任何数据。不知何故,文件的.gz扩展名让服务器误以为它是自己的响应之一,或者类似的情况。将文件扩展名更改为.bin,它就能正常工作。我真的不确定服务器为什么会这样行为,也不确定这是否只是一个stackblitz的问题,还是默认配置的问题。我在我的本地主机上尝试过(几乎是最基本的apache配置),它能正常工作,所以这可能是一个stackblitz的问题。 - undefined
显示剩余18条评论
1个回答

3
感谢 @kaiido 的帮助(请参阅问题评论),我们发现这个错误是由 Vite 服务器引起的。开发服务器以错误的头部信息提供 .gz 文件。
"content-encoding": "gzip"
​​"content-length": "42"
"content-type": "text/plain"

一个解决方法是将文件重命名为不同的扩展名(例如,hello.txt.gzhello.txt.gzip)。

相关的 Vite 问题


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接