// 将十六进制字符串转中文:hex为十六进制字符串 encoding为编码格式,默认是utf-8
export function hexToStr(hex,encoding) {
// 去掉字符串首尾空格
let trimedStr = hex.trim()
// 判断trimedStr前两个字符是否为0x,如果是则截取从第三个字符及后面所有,否则返回全部字符
let rawStr = trimedStr.substr(0, 2).toLowerCase() === "0x" ? trimedStr.substr(2) : trimedStr
// 得到rawStr的长度
let len = rawStr.length
// 如果长度不能被2整除,那么传入的十六进制值有误,返回空字符
if (len % 2 !== 0) {
return ""
}
let curCharCode // 接收每次循环得到的字符
let resultStr = [] // 存转换后的十进制值数组
for (let i = 0; i < len; i = i + 2) {
curCharCode = parseInt(rawStr.substr(i, 2), 16)
resultStr.push(curCharCode)
}
// encoding为空时默认为utf-8
let bytesView = new Uint8Array(resultStr) // 8 位无符号整数值的类型化数组
// TextEncoder和TextDecoder对字符串和字节流互转
let str = new TextDecoder(encoding).decode(bytesView)
return str
}
不知道为什么用上面网友给的FastestSmallestTextEncoderDecoder这个一直引入不到里面的方法,
找网友要了两个js包就可以了,
https://github.com/123456789xzxz/miniprogram/blob/main/miniprogram-text-decoder.js
https://github.com/123456789xzxz/miniprogram/blob/main/miniprogram-text-encoder.js
然后按需要引入就行
import TextDecoder from './miniprogram-text-decoder'
import TextEncoder from './miniprogram-text-encoder'
https://github.com/123456789xzxz/miniprogram/blob/main/miniprogram-text-decoder.js
https://github.com/123456789xzxz/miniprogram/blob/main/miniprogram-text-encoder.js
文件下载来后,引入小程序:
import TextDecoder from '@/utils/miniprogram-text-decoder'
使用方式:
let tempUint8Array = new Uint8Array(0)
const requestTask = wx.request({
url: baseURL,
timeout: 15000,
method: ’post‘,
enableChunked: true, // 开启分片模式
header: { },
data: param
})
requestTask.onChunkReceived((response) => {
const arrayBuffer = new Uint8Array(response.data)
let str = new TextDecoder().decode(arrayBuffer)
console.log('deMessage', str)
}
可以替换为https://github.com/inexorabletash/text-encoding
const TextEncoderLib = require('./lib/encoding.js'); new TextEncoderLib.TextEncoder(); new TextEncoderLib.TextDecoder();
const TextEncoderLib = require('./lib/encoding.js');
const decoder = new TextEncoderLib.TextDecoder('utf-8')
newData = decoder.decode(response.data)
我也分享一下遇到的坑,TextDecoder浏览器自带的API,在微信开发者工具中可以使用,在真机小程序环境没有这个方法,所以会报错的。然后找替代的
String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)); //在真机上会遇到个溢出报错,乱码的问题好像也有 text-encoding-shim 这个库,在微信开发者工具中表现正常,安卓手机部分表现正常,iOS手机基本会遇到问题。而且好像有乱码的情况 fastestsmallesttextencoderdecoder 方法错误 text-encoding-utf-8 真机OK,微信开发者工具失败
小程序不支持 TextEncoder / TextDecoder 。
请参考 MDN ,考虑使用 polyfill 。
function textDecode(data:any){ let txt; // 进行判断返回的对象是Uint8Array(开发者工具)或者ArrayBuffer(真机) // 1.获取对象的准确的类型 const type = Object.prototype.toString.call(data); // Uni8Array的原型对象被更改了所以使用字符串的信息进行判断。 if(type ==="[object Uint8Array]"){ //console.log("Uint8Array"); txt=decodeURIComponent(escape(String.fromCharCode(...data))) }else if(data instanceof ArrayBuffer){ // 将ArrayBuffer转换为Uint8Array //console.log("ArrayBuffer"); const uint8Array = new Uint8Array(data); txt=decodeURIComponent(escape(String.fromCharCode(...uint8Array))) } return txt; } 直接使用方法 const chunkText = textDecode(res.data);
uni-app,vue3,参考 https://github.com/123456789xzxz/miniprogram/blob/main/miniprogram-text-decoder.js,将以下代码另存为 @/utils/miniprogram-text-decoder.js,使用:
import { TextDecoderPolyfill } from '@/utils/miniprogram-text-decoder'; const decoder = new TextDecoderPolyfill(); const arrayBuffer = uni.base64ToArrayBuffer(decoder.decode(response.data)) const data = decoder.decode(arrayBuffer)
"use strict"; let TextDecoderPolyfill; const e = String.fromCharCode, t = Object.prototype.toString, r = t.call(ArrayBuffer.prototype), o = "undefined" != typeof SharedArrayBuffer ? t.call(SharedArrayBuffer) : "", d = function(t) { const r = t.charCodeAt(0), o = 0 | t.length; let d = 1114112, c = 0, a = ""; switch (r >>> 4) { case 12: case 13: d = (31 & r) << 6 | 63 & t.charCodeAt(1), c = d < 128 ? 0 : 2; break; case 14: d = (15 & r) << 12 | (63 & t.charCodeAt(1)) << 6 | 63 & t.charCodeAt(2), c = d < 2048 ? 0 : 3; break; case 15: r >>> 3 == 30 && (d = (7 & r) << 18 | (63 & t.charCodeAt(1)) << 12 | (63 & t.charCodeAt(2)) << 6 | t .charCodeAt(3), c = d < 65536 ? 0 : 4) } for (c && (o < c ? c = 0 : d < 65536 ? a = e(d) : d < 1114112 ? (d = d - 65664 | 0, a = e(55296 + (d >>> 10) | 0, 56320 + (1023 & d) | 0)) : c = 0); c < o; c = c + 1 | 0) a += " "; return a }, c = ["utf-8", "utf8", "unicode-1-1-utf-8"]; class a { constructor(e, t) { if (this.encoding = "utf-8", this.fatal = !1, this.ignoreBOM = !1, e && -1 === c.indexOf(e .toLowerCase())) throw new RangeError( `Failed to construct 'TextDecoder': The encoding label provided ('${e}') is invalid.`); if (t) { if (t.fatal) throw new Error( "Failed to construct 'TextDecoder': the 'fatal' option is unsupported."); if (t.ignoreBOM) throw new Error( "Failed to construct 'TextDecoder': the 'ignoreBOM' option is unsupported.") } } decode(c, a) { if (a && a.stream) throw new Error("Failed to decode: the 'stream' option is unsupported."); const i = c && c.buffer || c, n = t.call(i); if (n !== r && n !== o && void 0 !== c) throw TypeError( "Failed to execute 'decode' on 'TextDecoder': The provided value is not of type '(ArrayBuffer or ArrayBufferView)'" ); const f = new Uint8Array(i); let l = ""; for (let t = 0, r = 0 | f.length; t < r; t = t + 32768 | 0) l += e.apply(0, f.subarray(t, t + 32768 | 0)); return l.replace(/[\xc0-\xff][\x80-\xbf]+|[\x80-\xff]/g, d) } toString() { return "[object TextDecoder]" } } "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(a.prototype, Symbol.toStringTag, { value: "TextDecoder" }), TextDecoderPolyfill = a export { TextDecoderPolyfill }
请问后面怎么解决了 我也遇到这个问题 导入了require("encoding-indexes.js");require("encoding.js");依旧不可以;
开发者工具可以,但是真机预览不可以
https://github.com/anonyco/FastestSmallestTextEncoderDecoder
https://github.com/anonyco/FastestSmallestTextEncoderDecoder/blob/master/EncoderDecoderTogether.min.js
把CDN资源下载下来,小程序里直接require()引入,全局就有TextEncoder / TextDecoder 了。
// app.js
reuiqre('path/to/EncoderDecoderTogether.min.js')
记得 需要npm构建