两年前,Renato Mangini 介绍了一种在原始 ArrayBuffers 和相应数据的相应字符串表示形式之间进行转换的方法。在这篇博文的末尾,Renato 提到,用于处理这种转换的官方标准化 API 还处于起草阶段。规范现已成熟,并且 Firefox 和 Google Chrome 都添加了对 TextDecoder 和 TextEncoder 接口的原生支持。
正如此实时示例(如下方摘录的)所示,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 在当前浏览器中是否可用。