使用 编码 API 更轻松地将 ArrayBuffer 转换为字符串

两年前,Renato Mangini 介绍了一种在原始 ArrayBuffers 与该数据的对应字符串表示形式之间进行转换的方法。在帖子的最后,Renato 提到一个用于处理转换的官方标准化 API 尚处于草拟阶段。规范现已成熟,FirefoxGoogle Chrome 都增加了对 TextDecoderTextEncoder 接口的原生支持。

如下面摘录的此实时示例所示,Encoding API 可让您轻松地在原始字节和原生 JavaScript 字符串之间进行转换,而无需考虑您需要使用众多标准编码中的哪一种。

<pre id="results"></pre>

<script>
    if ('TextDecoder' in window) {
    // The local files to be fetched, mapped to the encoding that they're using.
    var filesToEncoding = {
        'utf8.bin': 'utf-8',
        'utf16le.bin': 'utf-16le',
        'macintosh.bin': 'macintosh'
    };

    Object.keys(filesToEncoding).forEach(function(file) {
        fetchAndDecode(file, filesToEncoding[file]);
    });
    } else {
    document.querySelector('#results').textContent = 'Your browser does not support the Encoding API.'
    }

    // Use XHR to fetch `file` and interpret its contents as being encoded with `encoding`.
    function fetchAndDecode(file, encoding) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', file);
    // Using 'arraybuffer' as the responseType ensures that the raw data is returned,
    // rather than letting XMLHttpRequest decode the data first.
    xhr.responseType = 'arraybuffer';
    xhr.onload = function() {
        if (this.status == 200) {
        // The decode() method takes a DataView as a parameter, which is a wrapper on top of the ArrayBuffer.
        var dataView = new DataView(this.response);
        // The TextDecoder interface is documented at http://encoding.spec.whatwg.org/#interface-textdecoder
        var decoder = new TextDecoder(encoding);
        var decodedString = decoder.decode(dataView);
        // Add the decoded file's text to the <pre> element on the page.
        document.querySelector('#results').textContent += decodedString + '\n';
        } else {
        console.error('Error while requesting', file, this);
        }
    };
    xhr.send();
    }
</script>

上面的示例使用功能检测来确定所需的 TextDecoder 接口在当前浏览器中是否可用,如果不可用,则显示错误消息。在实际应用中,如果无法获得原生支持,您通常需要采用替代实现方式。幸运的是,Renato 在他的原文中提到的文本编码库仍然是一个不错的选择。该库在支持原生方法的浏览器上使用原生方法,并在尚未添加支持的浏览器上为 Encoding API 提供 polyfill。

更新,2014 年 9 月:修改了示例,以说明如何检查 Encoding API 在当前浏览器中是否可用。