XMLHttpRequest返回的字符编码错误

5

我使用XMLHttpRequest来读取PDF文档http://www.virtualmechanics.com/support/tutorials-spinner/Simple2.pdf

%PDF-1.3
%âãÏÓ
[...]

并将其内容打印到控制台:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status === 200) {
      console.log(xhr.responseText);
      console.log('âãÏÓ');
    }
};
xhr.open('GET', 'http://www.virtualmechanics.com/support/tutorials-spinner/Simple2.pdf', true);
xhr.send();

然而,控制台显示:
%PDF-1.3
%����
[...]
âãÏÓ

(上述最后一行是为了验证控制台是否能够实际显示那些字符,而引用了上面的console.log。) 显然,在某些时候这些字符被错误地编码了。出了什么问题以及如何修复它?


可能是您的控制台字体没有包含 âãÏÓ 这些字符的字形... - mkl
@mkl 是的,已经编辑过问题了。 - Nico Schlömer
1
啊,我一开始没看到,你使用了 XMLHttpRequest.responseText。这个属性已经试图将响应解释为文本,但似乎失败了。PDF 文件不是文本文件,因此不应该被视为文本。你可能想尝试使用 XMLHttpRequest.response,另外可以参考 MDN 的 发送和接收二进制数据 页面。 - mkl
2个回答

4

XMLHttpRequest的默认响应类型是text,但这里实际上处理的是二进制数据。 Eric Bidelman描述了如何处理它。

解决问题的方法是将数据作为Blob读取,然后从Blob中提取数据并将其插入hash.update(..., 'binary')中:

var xhr = new XMLHttpRequest();
xhr.open('GET', details.url, true);
xhr.responseType = 'blob';
xhr.onload = function() {
  if (this.status === 200) {
    var a = new FileReader();
    a.readAsBinaryString(this.response);
    a.onloadend = function() {
      var hash = crypto.createHash('sha1');
      hash.update(a.result, 'binary');
      console.log(hash.digest('hex'));
    };
  }
};
xhr.send(null);

3

您的文件的MIME类型可能不是UTF-8。尝试按照此处所建议的进行覆盖,如下图所示:

xhr.open('GET', 'http://www.virtualmechanics.com/support/tutorials-spinner/Simple2.pdf', true);
xhr.overrideMimeType('text/xml; charset=iso-8859-1');
xhr.send();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接