【问题标题】:Conversion from Uint8Array to UTF-16 string freezes/crashes browser从 Uint8Array 转换为 UTF-16 字符串冻结/崩溃浏览器
【发布时间】:2016-11-03 20:31:11
【问题描述】:

我正在从服务器获取某种编码数据,这些数据应该被正确解码并在客户端显示为字符串(UTF-16)。目前我正在做这样的事情:

_decodeContent: function(encodedContent) {
  var binaryContent = atob(encodedContent);
  var result = pako.inflate(binaryContent, { to: 'string' });

  return result;
}

在大多数情况下,它工作正常。但有时客户端必须处理大量数据,因此它会冻结(Google Chrome 51.0.2704.84)甚至崩溃(Chromium 50.0.2661.102)浏览器选项卡。所以我发现,问题在于 pako 的 inflate 方法中的 { to: 'string' } 选项,同时尝试将包含大约 50kk 个元素的 Uint8Array 转换为 UTF-16 字符串。

我尝试以如下方式手动转换:

_decodeContent: function(encodedContent) {
  var binaryContent = atob(encodedContent);
  var utf8 = pako.inflate(binaryContent);
  var result = String.fromCharCode.apply(null, utf8);

  return result;
}

但它会产生:Uncaught RangeError: Maximum call stack size exceeded

所以现在我正在寻找解决方案,以使工作更快,或者至少防止浏览器崩溃。有什么想法吗?

UPD: 尝试使用块执行 String.fromCharCode.apply 以防止异常。所以异常的问题得到了解决,但它的运行速度比第一个解决方案慢了两倍。

UPD:所以问题是如何将大量的 Uint8Array 转换为 UTF-16 字符串以防止浏览器冻结。

【问题讨论】:

  • encodedContent 到底是什么?为什么不直接发送正确编码的 HTTP 标头,让浏览器为您进行必要的解码?
  • 原来是 GZIP Base64 字符串。所以,我不认为它那么简单。
  • 为什么是base64?只需 gzip 并使用 Content-Encoding: gzip 发送。
  • 不幸的是,影响这种数据编码超出了我的能力范围。我只需要找出在客户端处理如此大量数据的可能方法。
  • 顺便说一句,服务器仍然使用这个字符串的 UTF-8 版本。所以这并不能解决问题。

标签: javascript string google-chrome v8 pako


【解决方案1】:

我使用TextDecoder() 避免了 Firefox 86 浏览器在 100 MB 字符串上崩溃,不需要分块。大字符串上的 YMMV。

更新:建议已在库中实施(问题 #228)

如果可以避免,请使用浏览器和服务器内置的 Content-Encoding: gzip,这样会更快,并且可以为您节省导入库。

【讨论】:

    猜你喜欢
    • 2015-07-11
    • 1970-01-01
    • 2012-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-06
    • 2010-09-21
    • 2014-02-05
    相关资源
    最近更新 更多