开发者问题收集

将数组缓冲区转换为字符串 - 超出最大调用堆栈大小

2018-03-06
11623

我们的应用下载了一个 zip 文件,但响应是二进制的。

所以我做的是将其转换为 base64。当大小为 87.7KB 时它可以工作,但当响应大小为 183KB 时会发生错误。

错误为 Uncaught RangeError: Maximum call stack size reached

有问题的行是

btoa(String.fromCharCode.apply(null, new Uint8Array(blob)))

根据 这个答案 String.fromCharCode.apply() 必须替换为 TextEncoder

所以我将其更改为

btoa(new TextDecoder('utf-8').decode(new Uint8Array(blob)))

但出现错误。

未捕获的 DOMException:无法在“Window”上执行“btoa”:要编码的字符串包含 Latin1 范围之外的字符。

我再次使用此 答案 的最顶部代码片段对其进行了更改。

新代码现在是

btoa(unescape(encodeURIComponent(new TextDecoder('utf-8').decode(new Uint8Array(blob)))))

下载现在可以正常工作,但下载的 zip 文件已损坏。

整个代码可以在 这里 看到。

2个回答

我从另一个问题中得到了答案

btoa(new Uint8Array(blob).reduce(function (data, byte) {
    return data + String.fromCharCode(byte);
}, ''));

来源

Dev
2018-03-06

https://stackoverflow.com/a/40077712/6582356

function blobToB64(data) {
    if ('TextDecoder' in window) {
      // Decode as UTF-8
      var dataView = new DataView(data);
      var decoder = new TextDecoder('utf8');
      return btoa(decoder.decode(dataView));
    } else {
      // Fallback
      return btoa(new Uint8Array(data).reduce((data, byte) =>
        data + String.fromCharCode(byte),
        ''))
    }
}

https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder

这个似乎性能更好

Benito Gómez
2019-07-28