【发布时间】:2020-06-12 16:40:53
【问题描述】:
我正在下载带有axios 的压缩文件。为了进一步处理,我需要获取已下载的“原始”数据。据我所知,在 Javascript 中有两种类型:Blobs 和 Arraybuffers。两者都可以在请求选项中指定为responseType。
在下一步中,需要解压缩 zip 文件。我为此尝试了两个库:js-zip 和 adm-zip。两者都希望数据成为 ArrayBuffer。到目前为止一切顺利,我可以将 blob 转换为缓冲区。在这种转换之后,adm-zip 总是很高兴地提取 zip 文件。但是,js-zip 会抱怨文件损坏,除非该 zip 已使用 'arraybuffer' 作为 axios responseType 下载。 js-zip 不适用于取自 blob 的 buffer。
这让我很困惑。我认为ArrayBuffer 和Blob 本质上只是对底层内存的看法。将某些内容下载为 blob 与缓冲区之间可能存在性能差异。但是结果数据应该是一样的吧?
好吧,我决定尝试一下,发现了这个:
如果指定responseType: 'blob',axios 会将response.data 转换为字符串。假设您对这个字符串进行哈希处理并获得哈希码 A。然后将其转换为缓冲区。对于此转换,您需要指定编码。根据编码的不同,你会得到各种新的哈希值,我们称它们为 B1、B2、B3……当指定 'utf8' 作为编码时,我会回到原来的哈希值 A。
所以我猜当以'blob' 格式下载数据时,axios 会隐式将其转换为使用 utf8 编码的字符串。这似乎很合理。
现在您指定responseType: 'arraybuffer'。 Axios 为您提供了一个缓冲区response.data。对缓冲区进行哈希处理,得到哈希码 C。此代码与 A、B1、B2、...中的任何代码都不对应
那么当以'arraybuffer' 下载数据时,您会得到完全不同的数据吗?
现在对我来说,如果数据以'blob' 的形式下载,解压缩库 js-zip 会报错。它实际上可能以某种方式损坏。但是 adm-zip 是如何提取它的呢?我检查了提取的数据,它是正确的。这可能只是这个特定的 zip 存档的情况,但仍然让我感到惊讶。
这是我用于实验的示例代码:
//typescript import syntax, this is executed in nodejs
import axios from 'axios';
import * as crypto from 'crypto';
axios.get(
"http://localhost:5000/folder.zip", //hosted with serve
{ responseType: 'blob' }) // replace this with 'arraybuffer' and response.data will be a buffer
.then((response) => {
console.log(typeof (response.data));
// first hash the response itself
console.log(crypto.createHash('md5').update(response.data).digest('hex'));
// then convert to a buffer and hash again
// replace 'binary' with any valid encoding name
let buffer = Buffer.from(response.data, 'binary');
console.log(crypto.createHash('md5').update(buffer).digest('hex'));
//...
这里有什么不同,我如何获得“真实”的下载数据?
【问题讨论】:
标签: javascript node.js axios blob arraybuffer