Skip to main content
 首页 » 编程设计

javascript之ArrayBufferView 未捕获错误 : INDEX_SIZE_ERR: DOM Exception 1

2025年05月04日33飞鱼

我从 python 服务器通过 websocket 发送二进制数据:

data = struct.pack('!BI', 2, 1) 
channel.send(channel.BINARY, data) 

数据发送正常。 在客户端 javascript 是这样获取的:

onbinarydata: function(data) { 
    alert(data.byteLength); 
    >> 5 
    var array = new Uint8Array(data,0,1); 
    alert(array[0]); 
    >> 2 
    var array2 = new Uint32Array(data,1,5); 
    >> Uncaught Error: INDEX_SIZE_ERR: DOM Exception 1 
    alert(array2[0]); 

这怎么会发生? 字节长度减字节偏移为4,BYTY_ELEMENT_SIZE也为4。 读取第一个值没有问题,但接下来总是会引发错误,无论它是什么类型。 即使我只像这样设置字节偏移量

var array2 = new Uint32Array(data,1); 

有一个错误。

请您参考如下方法:

不能创建偏移量不能被 4 整除的 int32/uint32 数组。对于 int16/uint16 和 2 也是如此。

这是CPU架构的限制。

让这 2 个变量为 A:Uint16 和 B:Uint8。您可以使用不同的方法将它们映射到字节:

  • BBAA(将值 B 放入 Uint16)
  • 0BAA/B0AA(对齐跳过 1 个字节)
  • AAB(对齐重新排序)。

如果您不想考虑 big-/little-endiad、重新排序和其他东西...即,如果出于某种原因您仍想将变量放入字节中作为 BAA,那么使用以下想法:

对于每一个不对齐的变量放入相应大小的缓冲区,逐字节复制。 如果misalign为2个字节,则可以按对字节进行复制。

var array = new Uint8Array(data,0,1); 
alert(array); 
 
var array2 = new Uint8Array(data,1,5); 
var abuf2 = new ArrayBuffer(4); 
var abuf2_8 = new Uint8Array(abuf2); 
// using `subarray` won't help, cause it doesn't create a copy like `slice` 
// and the same data will have the same inconsistent memory alignment 
for (var i = 0; i < 4; i++) abuf2_8[i] = array2[i]; 
var abuf2_32 = new Uint32Array(abuf2); 
alert(abuf2_32[0]); 

顺便说一句,在 js 中有一些现成的打包/解包代码:

类似于php pack

我的代码对你来说可能更有趣,因为有两个类:打包成二进制字符串和打包成数组缓冲区。