使用pako.js压缩、解压数据

21世纪暴躁小码农

最近发现有个接口响应时间很长,查看network发现数据量比较大,导致需要用近3秒才能完成请求。于是决定后端压缩数据后再发给前端解压,顺便把发送数据的地方也改成了压缩数据。
本文用到的插件有:pako.jsjs-base64

废话不多说,附上demo:

demo使用cdn引入插件

<script src="https://cdn.bootcdn.net/ajax/libs/pako/2.0.4/pako.es5.js"></script>
<script src="https://cdn.jsdelivr.net/npm/js-base64@3.7.2/base64.min.js"></script>

压缩、解压的方法

// 压缩
zip = (data) => {
  if (!data) return data
  // 判断数据是否需要转为JSON
  const dataJson = typeof data !== 'string' && typeof data !== 'number' ? JSON.stringify(data) : data

  // 使用Base64.encode处理字符编码,兼容中文
  const str = Base64.encode(dataJson)
  let binaryString = pako.gzip(str);
  let arr = Array.from(binaryString);
  let s = "";
  arr.forEach((item, index) => {
    s += String.fromCharCode(item)
  })
  return btoa(s)
}

// 解压
unzip = (b64Data) => {
  let strData = atob(b64Data);
  let charData = strData.split('').map(function (x) {
    return x.charCodeAt(0);
  });
  let binData = new Uint8Array(charData);
  let data = pako.ungzip(binData);

  // ↓切片处理数据,防止内存溢出报错↓
  let str = '';
  const chunk = 8 * 1024
  let i;
  for (i = 0; i < data.length / chunk; i++) {
    str += String.fromCharCode.apply(null, data.slice(i * chunk, (i + 1) * chunk));
  }
  str += String.fromCharCode.apply(null, data.slice(i * chunk));
  // ↑切片处理数据,防止内存溢出报错↑
        
  const unzipStr = Base64.decode(str);
  let result = ''

  // 对象或数组进行JSON转换
  try {
    result = JSON.parse(unzipStr)
  } catch (error) {
    if (/Unexpected token o in JSON at position 0/.test(error)) {
      // 如果没有转换成功,代表值为基本数据,直接赋值
      result = unzipStr
     }
   }
   return result
}

执行结果:

const obj = [
  { a: 1, b: 2, c: 'hahaha 我 哈哈哈' },
  { a: 1, b: 5, c: 'hahaha 你 哈哈哈' },
  { a: 1, b: 3, c: 'hahaha 它 哈哈哈' },
  { a: 1, b: 22, c: 'hahaha 他 哈哈哈' },
  { a: 1, b: 24, c: 'hahaha 她 哈哈哈' },
  { a: 1, b: 21, c: 'hahaha 来 哈哈哈' }
]
const data = zip(obj)
console.log(data, 'data+++++++++++');
const result = unzip(data)
console.log(result, 'result++++++++++');

image.png

const obj = {
  a: [1, 2, 3],
  b: {
    b1: 'sjflk',
    b2: 'bmljsdjl'
  },
  c: '1,23,4,12,4',
  d: null,
  e: 123,
  f: '哈哈'
}
const data = zip(obj)
console.log(data, 'data+++++++++++');
const result = unzip(data)
console.log(result, 'result++++++++++');

image.png

const data = zip(123)
console.log(data, 'data+++++++++++');
const result = unzip(data)
console.log(result, 'result++++++++++');

image.png
现在项目基本都是用vue,react来做的,用到的插件附上了npm的链接,需要用es6版的请自行查看并调整逻辑。
另外,如果有写的不对的地方,欢迎各位看官帮忙指出。

阅读 1.4k
16 声望
0 粉丝
0 条评论
16 声望
0 粉丝
宣传栏