项目开发的通信模块用到了TextEncoder 和TextDecoder 但是在原生环境ios出包的时候报错了typeof TextEncoder === "undefined"
错误,应该环境没有这两个类的实现,于是想到了要寻找一个Polyfill。下面简单的介绍一下。
关于这两个类的Polyfill 还是蛮多的,自己搜索得到一个性能和功能都不错的类库。FastestSmallestTextEncoderDecoder
下面简单的介绍一下:
环境 类库地址:https://github.com/anonyco/FastestSmallestTextEncoderDecoder
把下面的源码直接放到项目内,运行时加载即可。
代码源码 FastestTextDecoderPolyfill.src.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 (function (window ){ "use strict" ; var log = Math .log ; var LN2 = Math .LN2 ; var clz32 = Math .clz32 || function (x ) {return 31 - log (x >>> 0 ) / LN2 | 0 }; var fromCharCode = String .fromCharCode ; var Object _prototype_toString = ({}).toString ; var NativeSharedArrayBuffer = window ["SharedArrayBuffer" ]; var sharedArrayBufferString = NativeSharedArrayBuffer ? Object _prototype_toString.call (NativeSharedArrayBuffer ) : "" ; var NativeUint8Array = window .Uint8Array ; var patchedU8Array = NativeUint8Array || Array ; var arrayBufferString = Object _prototype_toString.call ((NativeUint8Array ? ArrayBuffer : patchedU8Array).prototype ); function decoderReplacer (encoded ){ var cp0 = encoded.charCodeAt (0 ), codePoint=0x110000 , i=0 , stringLen=encoded.length |0 , result="" ; switch (cp0 >>> 4 ) { case 12 : case 13 : codePoint = ((cp0 & 0x1F ) << 6 ) | (encoded.charCodeAt (1 ) & 0x3F ); i = codePoint < 0x80 ? 0 : 2 ; break ; case 14 : codePoint = ((cp0 & 0x0F ) << 12 ) | ((encoded.charCodeAt (1 ) & 0x3F ) << 6 ) | (encoded.charCodeAt (2 ) & 0x3F ); i = codePoint < 0x800 ? 0 : 3 ; break ; case 15 : if ((cp0 >>> 3 ) === 30 ) { codePoint = ((cp0 & 0x07 ) << 18 ) | ((encoded.charCodeAt (1 ) & 0x3F ) << 12 ) | ((encoded.charCodeAt (2 ) & 0x3F ) << 6 ) | encoded.charCodeAt (3 ); i = codePoint < 0x10000 ? 0 : 4 ; } } if (i) { if (stringLen < i) { i = 0 ; } else if (codePoint < 0x10000 ) { result = fromCharCode (codePoint); } else if (codePoint < 0x110000 ) { codePoint = codePoint - 0x10080 |0 ; result = fromCharCode ( (codePoint >>> 10 ) + 0xD800 |0 , (codePoint & 0x3ff ) + 0xDC00 |0 ); } else i = 0 ; } for (; i < stringLen; i=i+1 |0 ) result += "\ufffd" ; return result; } function TextDecoder (_, opts ){}; TextDecoder ["prototype" ]["decode" ] = function (inputArrayOrBuffer ){ var buffer = (inputArrayOrBuffer && inputArrayOrBuffer.buffer ) || inputArrayOrBuffer; var asObjectString = Object _prototype_toString.call (buffer); if (asObjectString !== arrayBufferString && asObjectString !== sharedArrayBufferString && inputArrayOrBuffer !== undefined ) throw TypeError ("Failed to execute 'decode' on 'TextDecoder': The provided value is not of type '(ArrayBuffer or ArrayBufferView)'" ); var inputAs8 = NativeUint8Array ? new patchedU8Array (buffer) : buffer; var resultingString = "" ; for (var index=0 ,len=inputAs8.length |0 ; index<len; index=index+32768 |0 ) resultingString += fromCharCode.apply (0 , inputAs8[NativeUint8Array ? "subarray" : "slice" ](index,index+32768 |0 )); return resultingString.replace (/[\xc0-\xff][\x80-\xbf]+|[\x80-\xff]/g , decoderReplacer); } if (!window ["TextDecoder" ]) window ["TextDecoder" ] = TextDecoder ; })(typeof global == "" + void 0 ? typeof self == "" + void 0 ? this : self : global );
FastestTextEncoderPolyfill.src.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 var ENCODEINTO_BUILD = true ;(function (window ){ "use strict" ; var log = Math .log ; var LN2 = Math .LN2 ; var clz32 = Math .clz32 || function (x ) {return 31 - log (x >>> 0 ) / LN2 | 0 }; var fromCharCode = String .fromCharCode ; var patchedU8Array = window .Uint8Array || Array ; var TextEncoderPrototype = TextEncoder ["prototype" ]; var GlobalTextEncoder = window ["TextEncoder" ]; var globalTextEncoderPrototype; var globalTextEncoderInstance; function encoderReplacer (nonAsciiChars ){ var point = nonAsciiChars.charCodeAt (0 )|0 ; if (0xD800 <= point) { if (point < 0xDC00 ) { var nextcode = nonAsciiChars.charCodeAt (1 )|0 ; if (0xDC00 <= nextcode && nextcode <= 0xDFFF ) { point = (point<<10 ) + nextcode - 0x35fdc00 |0 ; if (point > 0xffff ) return fromCharCode ( (0x1e <<3 ) | (point>>>18 ), (0x2 <<6 ) | ((point>>>12 )&0x3f ), (0x2 <<6 ) | ((point>>>6 )&0x3f ), (0x2 <<6 ) | (point&0x3f ) ); } else point = 65533 ; } else if (point <= 0xDFFF ) { point = 65533 ; } } if (point <= 0x07ff ) { return fromCharCode ((0x6 <<5 )|(point>>>6 ), (0x2 <<6 )|(point&0x3f )); } else return fromCharCode ( (0xe <<4 ) | (point>>>12 ), (0x2 <<6 ) | ((point>>>6 )&0x3f ), (0x2 <<6 ) | (point&0x3f ) ); } function TextEncoder ( ){}; TextEncoderPrototype ["encode" ] = function (inputString ) { var encodedString = inputString === void 0 ? "" : ("" + inputString).replace (/[\x80-\uD7ff\uDC00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]?/g , encoderReplacer); var len=encodedString.length |0 , result = new patchedU8Array (len); var i=0 ; for (; i<len; i=i+1 |0 ) result[i] = encodedString.charCodeAt (i) |0 ; return result; }; function polyfill_encodeInto (inputString, u8Arr ) { var encodedString = inputString === void 0 ? "" : ("" + inputString).replace (/[\x80-\uD7ff\uDC00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]?/g , encoderReplacer); var len=encodedString.length |0 , i=0 , char=0 , read=0 , u8ArrLen = u8Arr.length |0 , inputLength=inputString.length |0 ; if (u8ArrLen < len) len=u8ArrLen; putChars : { for (; i<len; i=i+1 |0 ) { char = encodedString.charCodeAt (i) |0 ; switch (char >>> 4 ) { case 0 : case 1 : case 2 : case 3 : case 4 : case 5 : case 6 : case 7 : read = read + 1 |0 ; case 8 : case 9 : case 10 : case 11 : break ; case 12 : case 13 : if ((i+1 |0 ) < u8ArrLen) { read = read + 1 |0 ; break ; } case 14 : if ((i+2 |0 ) < u8ArrLen) { read = read + 1 |0 ; break ; } case 15 : if ((i+3 |0 ) < u8ArrLen) { read = read + 1 |0 ; break ; } default : break putChars; } u8Arr[i] = char; } } return {"written" : i, "read" : inputLength < read ? inputLength : read}; }; if (ENCODEINTO_BUILD ) { TextEncoderPrototype ["encodeInto" ] = polyfill_encodeInto; } if (!GlobalTextEncoder ) { window ["TextEncoder" ] = TextEncoder ; } else if (ENCODEINTO_BUILD && !(globalTextEncoderPrototype = GlobalTextEncoder ["prototype" ])["encodeInto" ]) { globalTextEncoderInstance = new GlobalTextEncoder ; globalTextEncoderPrototype["encodeInto" ] = function (string, u8arr ) { var strLen = string.length |0 , u8Len = u8arr.length |0 ; if (strLen < ((u8Len >> 1 ) + 3 |0 )) { var res8 = globalTextEncoderInstance["encode" ](string); var res8Len = res8.length |0 ; if (res8Len < u8Len) { u8arr.set ( res8 ); return { "read" : strLen, "written" : res8.length |0 }; } } return polyfill_encodeInto (string, u8arr); }; } })(typeof global == "" + void 0 ? typeof self == "" + void 0 ? this : self : global );
思考 其实对应的类库还是很多的比如nodejs
环境下的 util
的TextEncoder
和TextDecoder
拓展一 1 2 3 4 5 6 "use strict" exports .TextEncoder = typeof TextEncoder !== "undefined" ? TextEncoder : require ("util" ).TextEncoder exports .TextDecoder = typeof TextDecoder !== "undefined" ? TextDecoder : require ("util" ).TextDecoder
参考地址:https://github.com/gozala/web-encoding
拓展二 nodeJs版本低于v11,可以安装moduletext-encodin
1 npm install text-encoding
1 2 3 4 5 6 if (typeof TextEncoder !== 'function' ) { const TextEncodingPolyfill = require ('text-encoding' ); window .TextEncoder = TextEncodingPolyfill .TextEncoder ; window .TextDecoder = TextEncodingPolyfill .TextDecoder ; }