背景
最近做的一个项目,传输的数据量较大所以想到了用压缩数据的方法来处理,后台用了自带的gzip库。而前端解压找到了 pako.js 这个完美的库。但是几次尝试后发现数据量一大就解压失败报错。
pako.min.js 百度网盘下载地址:
链接:https://pan.baidu.com/s/1nxZqqlN7ZfYYMldnvvrC1A
提取码:285z
pako 解压方法(不能解压过大的数据)
function unzip(b64Data){
var strData = atob(b64Data);
// Convert binary string to character-number array
var charData = strData.split('').map(function(x){return x.charCodeAt(0);});
// Turn number array into byte-array
var binData = new Uint8Array(charData);
// // unzip
var data = pako.inflate(binData);
// Convert gunzipped byteArray back to ascii string:
strData = String.fromCharCode.apply(null, new Uint16Array(data));
return strData;
}
错误信息
当数据量过大的时候会出现如下的错误信息:
RangeError: too many arguments provided for a function call
但是根据错误提示根本不能找到正确的解决问题的方向。
解决思路
只有数据量过大才会导致出错,说明 String.fromCharCode.apply 不能接受过长的数组,那么我们可以想到将数组进行拆分->解压->拼接。
解决代码
array = new Uint16Array(data)
var res = '';
var chunk = 8 * 1024;
var i;
for (i = 0; i < array.length / chunk; i++) {
res += String.fromCharCode.apply(null, array.slice(i * chunk, (i + 1) * chunk));
}
res += String.fromCharCode.apply(null, array.slice(i * chunk));
strData = res
完整代码
function unzip(b64Data){
var strData = atob(b64Data);
// Convert binary string to character-number array
var charData = strData.split('').map(function(x){return x.charCodeAt(0);});
// Turn number array into byte-array
var binData = new Uint8Array(charData);
// // unzip
var data = pako.inflate(binData);
// Convert gunzipped byteArray back to ascii string:
// strData = String.fromCharCode.apply(null, new Uint16Array(data));
array = new Uint16Array(data)
var res = '';
var chunk = 8 * 1024;
var i;
for (i = 0; i < array.length / chunk; i++) {
res += String.fromCharCode.apply(null, array.slice(i * chunk, (i + 1) * chunk));
}
res += String.fromCharCode.apply(null, array.slice(i * chunk));
strData = res
return strData;
}
这样就可以解压任意大小的数据啦啦啦。