Angular 2中如何解压服务器二次压缩后剩余的Gzip文件?
解决双重Gzip压缩响应的手动解压问题
我来帮你搞定这个双重压缩的棘手问题!你遇到的情况是服务器返回了经过两次Gzip压缩的内容,浏览器自动帮你解了第一层,但剩下的响应体还是Gzip格式,所以咱们得手动处理第二层解压,才能拿到最终的JSON数据。
步骤1:修改请求配置,获取二进制数据
首先,你需要调整http.get的请求选项,告诉Angular不要自动解析响应,而是返回原始的二进制数组(ArrayBuffer)——因为现在的响应是压缩的二进制内容,直接用response.json()会报错。
修改后的请求代码如下:
import * as pako from 'pako'; // 记得先安装pako库 // ...其他业务代码 return this.http.get(url, { headers: this.authHeader(), search, responseType: 'arraybuffer' // 关键:获取原始二进制数据,禁止自动解析 }) .catch(err => Observable.of(err)) .map((response: ArrayBuffer) => { // 1. 将ArrayBuffer转换为Uint8Array,pako库需要这种格式的输入 const compressedBytes = new Uint8Array(response); // 2. 使用pako解压第二层Gzip数据 const decompressedBytes = pako.inflate(compressedBytes); // 3. 将解压后的字节数组转换为UTF-8字符串 const jsonStr = new TextDecoder().decode(decompressedBytes); // 4. 解析为JSON对象并添加url属性 let jsonObject = JSON.parse(jsonStr); jsonObject.url = url; return jsonObject; });
步骤2:安装依赖库
上面用到了pako这个轻量级的压缩/解压库,它完美支持Gzip格式的解压,你需要先通过npm安装它:
npm install pako --save
额外注意事项
- 增强错误处理:建议在解压和JSON解析步骤添加try-catch,避免因为数据损坏导致整个流程崩溃:
.map((response: ArrayBuffer) => { try { const compressedBytes = new Uint8Array(response); const decompressedBytes = pako.inflate(compressedBytes); const jsonStr = new TextDecoder().decode(decompressedBytes); let jsonObject = JSON.parse(jsonStr); jsonObject.url = url; return jsonObject; } catch (err) { console.error('解压或解析JSON失败:', err); // 这里可以根据业务需求返回默认值,或者重新抛出错误 return { url, error: '数据处理失败' }; } })
- 浏览器自动解压的逻辑:浏览器只会自动处理响应头带有
Content-Encoding: gzip的内容,但如果服务器是先压缩一次、再压缩一次(双重压缩),第二次的压缩不会被浏览器识别,所以需要我们手动介入处理。
内容的提问来源于stack exchange,提问作者Dino
相关产品推荐
相关产品推荐

