【问题标题】:How to deal with non-ASCII UTF-8 characters across my application stack如何在我的应用程序堆栈中处理非 ASCII UTF-8 字符
【发布时间】:2020-02-07 22:54:35
【问题描述】:

我将国家/地区名称存储在通过 cpprest 服务器公开的 sqlite 数据库中。我的 Web 应用程序正在查询这些国家/地区名称,服务器返回的结果是原始二进制字符串(八位字节流),其中包含名称长度和名称的实际字符。

我正在将国家/地区名称读入 std::string 值,如下所示:

country->Label = std::string((const char*)sqlite3_column_text(Query.Statement, 1));

然后我将它们复制到 std::vector<char> 缓冲区中,然后通过 cpprest API 发送回

Concurrency::streams::bytestream::open_istream<std::vector<char>>(buffer);

当我的 Web 应用程序接收到数据时,我会像这样对其进行解码:

var data = new Uint8Array(request.response);
var dataView = new DataView(data.buffer);

var nameLength = dataView.getUint32(0, true);

var label = "";

for(var k = 0 ; k < nameLength; k++)
{                   
    label += String.fromCharCode([dataView.getUint8(k + 4)])
}

在大多数情况下,这工作正常,直到我遇到一个包含非 ASCII 字符的国家/地区名称,然后我才得到这个可恶的:

我对 UTF-8 的理解是,它将 ASCII 字符作为普通字符存储,但非 ASCII 字符存储在多个字节中。

我的应用程序堆栈的哪一部分需要被告知何时何地使用非 ASCII 字符的多个字节,我将如何去做?我的猜测是,由于 Web 应用程序是显示文本的应用程序,因此需要在此处进行更改,但我不确定如何进行。

编辑: 为了澄清起见,我尝试了提供的答案,但它们似乎也不起作用:

var labelArray = data.subarray(4, 4 + nameLength);                  
var label = new TextDecoder("utf-8").decode(labelArray);

结果如下:

【问题讨论】:

  • 这可能是 JavaScript 中的 fromCharCode(),是的。您将每个字节视为一个独立的代码点,而不是将其视为多字节编码的一部分。如果您阅读 cpprest 和 JavaScript 文档,可能有一种比所有字节流内容更简单的方法。
  • 为什么不正常使用 JSON 与 JavaScript 交互?
  • Web 应用程序不是标准的 Web 应用程序,它是交互式的,因此我们试图从中尽可能多地发挥性能,并删除 JSON 解析(在服务器端和客户端)是其中之一我们挤压系统的方式。
  • 我非常怀疑new TextDecoder("utf-8").decode() 会比让 JS 引擎原生解析 JSON 更快,这是它经过优化的目的。使用 gzip 内容编码,有效负载大小也几乎没有差异。

标签: javascript c++ sqlite utf-8 cpprest-sdk


【解决方案1】:
var data = new Uint8Array(request.response);
var string = new TextDecoder("utf-8").decode(data);

【讨论】:

  • 感谢您的回答,但不幸的是它似乎不起作用,我已经更新了我的问题以反映此解决方案会发生什么。
猜你喜欢
  • 1970-01-01
  • 2013-11-17
  • 2014-07-18
  • 1970-01-01
  • 1970-01-01
  • 2011-06-19
  • 2021-10-27
  • 2010-12-11
  • 1970-01-01
相关资源
最近更新 更多