微信小程序 ArrayBuffer转16进制,16进制转字符串(解决中文乱码)
场景应用
微信小程序使用TCP通讯,接收数据的类型为ArrayBuffer,转字符串后中文乱码。(uniapp开发)
// 原本使用方法
// 拿到TCP通讯的 ArrayBuffer 数据
let unit8Arr = new Uint8Array(arrayBuffer)
let encodedString = String.fromCharCode.apply(null, unit8Arr)
let decodedString = decodeURIComponent(escape((encodedString)))
// decodeURIComponent()函数报错 "URI malformed"
准备
由于微信小程序是阉割版的Web,没有TextDecoder,需要去https://github.com/inexorabletash/text-encoding ,下载文件 encoding.js 和 encoding-indexes.js。
ArrayBuffer转16进制
function buf2hex(arrayBuffer) {
return Array.prototype.map.call(new Uint8Array(arrayBuffer), x => ('00' + x.toString(16)).slice(-2)).join('');
}
16进制转字符串
/**
* 十六进制字符串转中文
* @param {String} hex 为十六进制字符串
* @return {String} 包含中文的字符串
*/
function hexToStr(hex) {
// 去掉字符串首尾空格
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)因为小程序中没有TextDecoder,经查阅资料,下载https://github.com/inexorabletash/text-encoding并const encoding = require("./text-encoding-master/lib/encoding.js")引入后使用下面方式即可:
let str = new encoding.TextDecoder("gbk").decode(bytesView)
return str
}
关键使用代码
import encoding from '@/xxx/encoding.js' // 引入js
// 微信开放文档关键函数 TCPSocket.onMessage()
this.TCPClient.onMessage((res => {
const arrayBuffer = res.message // 获取通讯数据,类型为ArrayBuffer
const data16 = buf2hex(arrayBuffer) // ArrayBuffer转16进制
const requestData = hexToStr(data16) // 16进制转字符串
console.log(requestData)
}))
参考
注:本文可分享可转发,转发请注明出自bug源