HarmonyOS ArkTs 解决流式传输编码问题
工作日志
日期:2024-11-15
标题:HarmonyOS ArkTs 解决流式传输编码问题
问题描述
- 问题:在处理流式数据的 HTTP 请求时,服务器返回的数据存在编码问题,导致数据无法正确地解码为字符串。部分数据在解码后出现了乱码,特别是 JSON 格式无法正确解析。
- 现象:接收到的响应数据在转换为字符串后包含乱码,无法正确转换为 JSON 格式,部分数据内容显示为
\uXXXX
之类的乱码字符。解析 JSON 时抛出异常,提示 “Unexpected token” 等错误信息。
原因分析
- 原因:问题的根本在于没有正确处理流式传输中的数据拼接和编码转换。原始实现中使用
ArrayBuffer
和手动逐字节转换的方式,这种方式在处理多次接收的数据时比较繁琐,且容易引发编码不匹配的问题。数据在拼接过程中也容易导致一些字符丢失或编码错误。
解决步骤
-
使用
Uint8Array
进行数据拼接:- 设置
Uint8Array
类型用于维护流式响应数据,这样可以方便地将每次接收到的数据进行拼接。 - 代码如下:
let resView = new Uint8Array(0); httpRequest.on('dataReceive', (data: ArrayBuffer) => { const newView = new Uint8Array(resView.length + data.byteLength); newView.set(resView, 0); newView.set(new Uint8Array(data), resView.length); resView = newView; console.info('Updated response length: ' + resView.length); });
- 设置
-
使用
TextDecoder
正确解码Uint8Array
:- 使用
TextDecoder
来解码Uint8Array
,以便正确地处理 UTF-8 编码的字符,避免手动逐字节转换可能引起的乱码。 - 代码如下:
function uint8ArrayToString(buffer: Uint8Array): string { const decoder = new util.TextDecoder('utf-8'); return decoder.decode(buffer); }
- 使用
-
处理数据结束并转换为字符串或 JSON:
- 在接收到完整数据之后,使用
TextDecoder
解码数据并尝试解析为 JSON。如果解析失败,则进行格式清理(例如将单引号替换为双引号),再尝试解析。 - 代码如下:
httpRequest.on('dataEnd', () => { console.info('No more data in response, data receive end'); let resultString = uint8ArrayToString(resView); try { let jsonData: undefined | string; try { jsonData = JSON.parse(resultString); } catch (error) { console.warn("Response could not be parsed as JSON directly."); let cleanedString = resultString.replace(/'/g, '"'); jsonData = JSON.parse(cleanedString); } console.info('Parsed response as JSON:', JSON.stringify(jsonData)); callback(JSON.stringify(jsonData)); } catch (e) { console.error('Failed to parse response:', e); console.info('Response as raw string:', resultString); callback(resultString); } });
- 在接收到完整数据之后,使用
-
验证问题是否解决:
- 通过多次调用接口并观察日志,确认所有返回数据均能正确解码为 UTF-8 格式,且能正确解析为 JSON。乱码问题彻底解决。
经验教训
- 总结:
- 在处理流式数据时,正确的编码和拼接方法非常重要。
Uint8Array
提供了更高效的方式来拼接和操作二进制数据。 - 使用
TextDecoder
代替手动字节解析是处理流式数据解码的最佳方式,可以有效避免编码错误和乱码问题。 - 遇到解析失败的情况时,尝试对数据格式进行清理是个有效的补救措施,尤其在数据格式不完全符合标准时,这种处理方式可以大大提高解析的成功率。
- 最终解决方案结合了数据的高效拼接和编码转换的正确方法,可以作为今后处理流式传输数据的最佳实践。
- 在处理流式数据时,正确的编码和拼接方法非常重要。