axios如何处理responseType为blob和arraybuffer的情况?
axios如何处理responseType为blob和arraybuffer的情况?
我正在使用axios下载一个zip文件。为了进一步处理,我需要获取已下载的“原始”数据。据我所知,在JavaScript中有两种类型可以实现这一点:Blobs和Arraybuffers。这两种类型都可以在请求选项中指定responseType
。
接下来,需要解压缩zip文件。我尝试了两个库:js-zip和adm-zip。这两个库都需要数据是ArrayBuffer类型。到目前为止,我可以将Blob转换为Buffer。在此转换之后,adm-zip总是可以成功提取zip文件。然而,js-zip会抱怨文件损坏,除非zip文件是以'arraybuffer'
作为axios的responseType
下载的。js-zip无法处理从Blob中获取的Buffer。
这让我感到非常困惑。我本以为ArrayBuffer和Blob本质上只是底层内存的视图。在以Blob或Buffer的方式下载文件之间可能存在性能差异。但结果数据应该是相同的,对吗?
好吧,我决定进行实验,并发现了以下结果:
如果你指定responseType: 'blob'
,axios会将response.data
转换为字符串。假设你对该字符串进行哈希处理并得到哈希码A。然后你将其转换为Buffer。在此转换中,你需要指定一种编码。根据编码的不同,你将得到各种新的哈希码,我们称之为B1、B2、B3,等等。当以'utf8'作为编码时,我可以得到原始哈希码A。
所以我猜当以'blob'
方式下载数据时,axios会隐式地将其转换为用utf8编码的字符串。这似乎非常合理。
现在你指定responseType: 'arraybuffer'
。Axios将以response.data
的形式提供一个Buffer。对该Buffer进行哈希处理,你将得到哈希码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')); //...
是什么导致了这种差异,我该如何获取“真实”的已下载数据?