3

我使用 ajax 从 Web 服务器读取二进制文件。HTTP 响应是 contentType: 'application/octet-stream' 并包含一个二进制字符串,它只是一个字节字符串(不是 unicode),例如(十六进制):

0x00 0x08 0x17 0xA1 0x01

注意:在 C 中,这将在内存中表示为 5 个字节:

char buf[5] = {0, 8, 23, 161, 1}

...但在 Javascript 中,这是一个字符串,其 ASCII 表示类似于“�”(我实际上无法正确粘贴它,因为并非所有字符都有可打印的表示)。

我现在需要将其转换为字符或整数数组,以便我可以访问字符串中每个字符的数值。但是,使用 charCodeAt() 函数遍历示例字符串会返回:

[0] 0
[1] 8
[2] 23
[3] 65533
[4] 1

因为 charCodeAt() 解码 unicode 字符,并且 0xA1 不被识别为有效的 unicode 字符,所以使用替换字符(65533) 代替。

我想得到以下信息:

[0] 0
[1] 8
[2] 23
[3] 161
[4] 1

如何做到这一点?

这是代码片段:

$.ajax({
url: url,
type: "get",
success: function(data) { // data contains binary representation of 0x00 0x08 0x17 0xA1 0x01
    var byteTab = []
    for (var n = 0; n < data.length; ++n) {
        byteTab.push(data.charCodeAt(n))
    }
})
4

2 回答 2

1

更新:我不太确定 [default] Ajax 在这种情况下是否适合这项工作。不管文件大小如何,使用流来适应未来的可扩展性通常是一个好习惯,因为您当前的方法一次加载所有内容。

本文介绍了如何创建一个自定义的 ajax 传输,该传输包装XmlHttpRequest将数据加载到数组缓冲区中。您可以这样做,将字节顺序推送到您的主数组中,然后从那里开始。

旧: 我不确定我是否正确理解了您的数据表示,但我相信您可以使用parseInt()将十六进制字符串转换为十进制:

var data = ['0x00', '0x08', '0x17', '0xA1', '0x01'];
var parsed = [];

for(var i = 0; i < data.length; i++) {
	parsed.push(parseInt(data[i], 16));
}

console.log(parsed);
console.log(parseInt('0xA1', 16))

如果这不是您的意思,请发表评论,我将尝试使用更具体的实现来更新我的答案。

于 2018-08-08T01:30:43.900 回答
1

根据Haus回答的建议,我找到了更多解决该问题的方法,因此我将在这里分享我的发现。

  1. 我首选的解决方案是使用ArrayBuffer来访问原始数据。不幸的是,根据本文, Ajax 似乎不支持它,尽管有一个添加支持的选项(我无法开始工作),并且没有直接的方法可以从字符串中创建 ArrayBuffer。但是 XMLHttpRequest 支持 ArrayBuffer 作为 responseType 如此处所述因此我将代码更改为以下内容,这可以满足我的要求:

    var xhr = new XMLHttpRequest();
    xhr.open('GET', url);
    xhr.responseType = 'arraybuffer';  
    xhr.onload = function() {
        if (this.status == 200) {
            var byteTab=[]
            var uint8View = new Uint8Array(this.response)
            for (var n = 0; n < uint8View.byteLength; n++) {
                byteTab.push(uint8View[n])
            }
    
        } 
    };
    xhr.send();
    
  2. 另一种解决方案是通过使用 Blob 到达 ArrayBuffer,在这个答案中用一个例子进行了解释

  3. 另一种选择是将 Blob 与 FileReader.readAsBinaryString() 结合使用,与此处的示例相同。使用 readAsBinaryString() 将 blob 转换为 unicode 字符串,然后可以使用 charCodeAt() 对其进行解析

于 2018-08-08T19:23:06.470 回答