小程序pako.js GZIP定义解压和压缩的方法 及小程序不能使用window.abot和window.btoa的解决方法

今天做了一个小程序幕帘弹框,接口请求返回的是一段压缩了的字符串,我使用了pako.js GZIP来解压缩,首先安装pako依赖

npm install pako

pako.js GZIP定义解压和压缩的方法

解压

unzipFun:function(b64Data) {
	let strData = atob(b64Data),
	charData = strData.split('').map(function(x){return x.charCodeAt(0);}),
	binData = new Uint8Array(charData),
	data = pako.inflate(binData);
	// strData = String.fromCharCode.apply(null, new  	Uint16Array(data));  
	// return decodeURIComponent(strData)(这里也可以直接return返回忽略下面步骤,但是这么做发现中文解压的时候乱码了,使用二进制转字符串的方法得以解决)
	strData=this.byteToString(data)  
	return strData  
 },
 //二进制转成字符串(解决解压时中文乱码的情况)
 byteToString:function (arr) {
		 if (typeof arr === 'string') {
			return arr;
		 }
	var str = '',
	_arr = arr;
    for (var i = 0; i < _arr.length; i++) {
			 var one = _arr[i].toString(2),
			 v = one.match(/^1+?(?=0)/);
			 if (v && one.length == 8) {
			       var bytesLength = v[0].length;
			       var store = _arr[i].toString(2).slice(7 - bytesLength);
			       for (var st = 1; st < bytesLength; st++) {
			         store += _arr[st + i].toString(2).slice(2);
			}
			str += String.fromCharCode(parseInt(store, 2));
			        i += bytesLength - 1;
			 } else {
			        str += String.fromCharCode(_arr[i]);
			 }
		}
	 return str;
},

压缩

 zipFun:function (str){
	 var binaryString = pako.gzip(encodeURIComponent(str), { to: 'string' })
	 return btoa(binaryString);
 },

小程序不能使用window.abot和window.btoa的解决方法

当我成功将幕帘弹框写好的时候,发现真机调试还是解压不出来,报错

原因是pako方法中使用到window.atob,而小程序不支持这个方法,所以导致报错。
解决方法:引入atob的polyfill,就是在小程序实现一个atob方法
atob polyfill 下载地址:https://github.com/davidchambers/Base64.js ( 该polyfill实现了atob和btoa)

(function(f) {

  'use strict';

  /* istanbul ignore else */
  if (typeof exports === 'object' && exports != null &&
      typeof exports.nodeType !== 'number') {
    module.exports = f ();
  } else if (typeof define === 'function' && define.amd != null) {
    define ([], f);
  } else {
    var base64 = f ();
    var global = typeof self !== 'undefined' ? self : $.global;
    if (typeof global.btoa !== 'function') global.btoa = base64.btoa;
    if (typeof global.atob !== 'function') global.atob = base64.atob;
  }

} (function() {

  'use strict';

  var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';

  function InvalidCharacterError(message) {
    this.message = message;
  }
  InvalidCharacterError.prototype = new Error ();
  InvalidCharacterError.prototype.name = 'InvalidCharacterError';

  // encoder
  // [https://gist.github.com/999166] by [https://github.com/nignag]
  function btoa(input) {
    var str = String (input);
    for (
      // initialize result and counter
      var block, charCode, idx = 0, map = chars, output = '';
      // if the next str index does not exist:
      //   change the mapping table to "="
      //   check if d has no fractional digits
      str.charAt (idx | 0) || (map = '=', idx % 1);
      // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8
      output += map.charAt (63 & block >> 8 - idx % 1 * 8)
    ) {
      charCode = str.charCodeAt (idx += 3 / 4);
      if (charCode > 0xFF) {
        throw new InvalidCharacterError ("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");
      }
      block = block << 8 | charCode;
    }
    return output;
  }

  // decoder
  // [https://gist.github.com/1020396] by [https://github.com/atk]
  function atob(input) {
    var str = (String (input)).replace (/[=]+$/, ''); // #31: ExtendScript bad parse of /=
    // if (str.length % 4 === 1) {
    //   throw new InvalidCharacterError ("'atob' failed: The string to be decoded is not correctly encoded.");
    // }
    for (
      // initialize result and counters
      var bc = 0, bs, buffer, idx = 0, output = '';
      // get next character
      buffer = str.charAt (idx++); // eslint-disable-line no-cond-assign
      // character found in table? initialize bit storage and add its ascii value;
      ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
        // and if not first of each 4 characters,
        // convert the first 8 bits to one ascii character
        bc++ % 4) ? output += String.fromCharCode (255 & bs >> (-2 * bc & 6)) : 0
    ) {
      // try to find character in table (0-63, not found => -1)
      buffer = chars.indexOf (buffer);
    }
    return output;
  }

  return {btoa: btoa, atob: atob};

}));

image

const polyfill = require('@/common/base64/base64.js');
const {atob} = polyfill;

以上写完就可以完美的解压成功啦!

知识巩固

atob() 方法用于解码使用 base-64 编码的字符串。
base-64 编码使用方法是 btoa() 。

encodeURIComponent() 函数可把字符串作为 URI 组件进行编码。
该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ’ ( ) 。
其他字符(比如 :;/?&=+$,# 这些用于分隔 URI 组件的标点符号),都是由一个或多个十六进制的转义序列替换的

posted @ 2023-01-03 15:59  wandoubaguo  阅读(882)  评论(0编辑  收藏  举报