Javascript 如何将arraybuffer转换为字符串

Javascript 如何将arraybuffer转换为字符串,javascript,node.js,google-chrome-app,arraybuffer,Javascript,Node.js,Google Chrome App,Arraybuffer,我在node.js上编写了一个简单的TCP服务器,用于向Chrome应用程序发送一些数据。在chrome应用程序中,当我获取数据时,我使用下面的函数将其转换为字符串,我得到一个异常“UINT16数组的字节长度应该是2的倍数。” 我找不到任何有关导致此问题的原因以及如何解决此问题的信息。任何关于这方面的建议都将受到高度赞赏 下面是node.js服务器中向客户端发送数据的代码: socket.on('data', function(data) { console.log('DATA ' +

我在node.js上编写了一个简单的TCP服务器,用于向Chrome应用程序发送一些数据。在chrome应用程序中,当我获取数据时,我使用下面的函数将其转换为字符串,我得到一个异常“UINT16数组的字节长度应该是2的倍数。”

我找不到任何有关导致此问题的原因以及如何解决此问题的信息。任何关于这方面的建议都将受到高度赞赏

下面是node.js服务器中向客户端发送数据的代码:

socket.on('data', function(data) {

    console.log('DATA ' + socket.remoteAddress + ': ' + data);
    // Write the data back to the socket, 
    //   the client will receive it as data from the server
    var r= socket.write('from server\r\n');

});
以下是chrome应用程序的代码:

  chrome.sockets.tcp.onReceive.addListener(function (info) {
            console.log('onListener registered');
            if (info.socketId != socketid)
                return;
            else {
                try {

                   data = ab2str(info.data);
                    console.log(data);
                }
                catch (e) {
                    console.log(e);
                }

            }
            // info.data is an arrayBuffer.
        });

 function ab2str(buf) {
    return String.fromCharCode.apply(null, new Uint16Array(buf));
}

您可能会看到这个问题,因为您的应用程序在套接字上接收到奇数个字节,但您正试图从中创建一个2字节宽的项目数组(因为这正适合
uint16数组

如果您的应用程序通过网络(5字节)接收到字符串
“Hello”
,则您可以将其转换为
Uint8Array
,如下所示:

Item:        0   1   2   3   4
Char:        H   e   l   l   o
Uint8 Value: 72  101 108 108 111
将其强制转换为
uint16阵列
,但将尝试执行以下操作:

Item   0     1     2
Chars  He    ll    o?
IntVal 25928 27756 ?????
如果没有第6个字节,它就无法构造数组,因此会出现异常

只有在套接字上需要UCS-2字符串数据时,才可以对数据使用
UINT16阵列。如果您正在接收普通ASCII数据,那么您希望将其转换为
Uint8Array
,并映射
String.fromCharCode
。如果它是其他的东西,比如UTF-8,那么你必须做一些其他的转换


不管怎样,套接字层总是可以自由地向您发送任意长度的数据块。你的应用程序将不得不处理奇数大小的数据,并保存你无法立即处理的任何剩余数据,以便你在接收下一个数据块时可以使用它。

有点过时,但也许使用此函数()效果更好(我将arraybuffer解码为字符串,而不会留下一些特殊字符作为总垃圾):

功能解码UTF8(arrayBuffer){
var结果=”;
var i=0;
var c=0;
var c1=0;
var c2=0;
var数据=新的Uint8Array(arrayBuffer);
//如果我们有BOM,跳过它
如果(data.length>=3&&data[0]==0xef&&data[1]==0xbb&&data[2]==0xbf){
i=3;
}
而(i191&&c<224){
如果(i+1>=data.length){
抛出“UTF-8解码失败。两字节字符被截断。”;
}
c2=数据[i+1];

result+=String.fromCharCode((c&31)有一种使用
Blob
FileReader
异步方法

您可以指定任何有效的编码

function arrayBufferToString( buffer, encoding, callback ) {
    var blob = new Blob([buffer],{type:'text/plain'});
    var reader = new FileReader();
    reader.onload = function(evt){callback(evt.target.result);};
    reader.readAsText(blob, encoding);
}

//example:
var buf = new Uint8Array([65,66,67]);
arrayBufferToString(buf, 'UTF-8', console.log.bind(console)); //"ABC"
现代(Chrome 38+)实现这一点的方法是,假设编码为UTF-8:

var decoder = new TextDecoder("utf-8");

function ab2str(buf) {
    return decoder.decode(new Uint8Array(buf));
}
这将使用
textdecker
API;有关更多选项,例如不同的编码,请参阅

function arrayBufferToString( buffer, encoding, callback ) {
    var blob = new Blob([buffer],{type:'text/plain'});
    var reader = new FileReader();
    reader.onload = function(evt){callback(evt.target.result);};
    reader.readAsText(blob, encoding);
}

//example:
var buf = new Uint8Array([65,66,67]);
arrayBufferToString(buf, 'UTF-8', console.log.bind(console)); //"ABC"

另请参见:

您能展示更多关于如何获取缓冲区的信息吗?一般来说,缓冲区是规范的。不过,我不打算使用dupehammer。这取决于应用程序——您可能希望使用Uint8Array,或者像我在上一段中所说的那样,缓冲任何尾随字节,然后在获取下一个数据包时将其用作第一个字节。我的问题是我有一个arraybuffer responsetype返回了一个错误,但错误中的部分文本包含带有重音的字符,它们被解码为垃圾,几乎无法读取。我尝试像OP一样使用UINT16数组对其进行解码,但得到了相同的错误。我最终发现了这个问题:并且我能够用OU正确解码字符串不需要使用Uint16Array。您可能需要寻找一种同步方式来实现。谢谢。非常好,但只受firefox和chrome的支持。IE和Safari需要一个大垫片。问题是关于chrome应用程序,所以运行时显式是chrome。对于不支持此API的其他浏览器,有一个解决方案。
var decoder = new TextDecoder("utf-8");

function ab2str(buf) {
    return decoder.decode(new Uint8Array(buf));
}