Node.js httpServer 接收前端 ArrayBuffer 二进制数据详解

作者:星河

时间:2026-10-22

浏览:349

本文详解在 Node.js 的 httpServer 中如何正确接收前端发送的 ArrayBuffer 二进制数据。针对 protobuf 交互中常见的数据错乱问题,指出需在 req.on('data') 事件中累积数据块,并在 req.on('end') 中使用 Buffer.concat 合并数组以生成完整 Buffer。文章提供了 Node.js 后端接收代码及 Three.js 前端发送点阵和图片 Buffer 的完整示例,确保二进制数据传输的准确性。

文章目录

Node.js 接收二进制数据的问题背景

近期在使用 protobuf 进行数据交互时,发现 Node.js 接收前端发送的二进制数据时出现了数据错误等问题。经过排查,发现根本原因在于代码逻辑处理不当,特别是在 req.on('data', () => {}) 事件中的处理方式引发了数据错乱。借此机会分享正确的处理思路与代码。

Node.js 接收 ArrayBuffer 的正确代码

首先直接展示接收二进制数据的正确代码实现。


const server = http.createServer((req, res) => {
    if(req.method==='OPTIONS'){
      res.setHeader("Access-Control-Allow-Origin", "*");
      res.statusCode=200;
    }
    if(req.method==='POST'){
     // 存储数组空间
     let msg=[];
     // 接收到数据消息
     req.on('data',(chunk)=>{
      if(chunk){
       msg.push(chunk);
      }
     })
     // 接收完毕
     req.on('end',()=>{
      // 对buffer数组阵列列表进行buffer合并返回一个Buffer
      let buf=Buffer.concat(msg);
      conosole.log(buf)//提取Buffer正确
     })         
}  
});
server.listen(3000,'127.0.0.1');

在 Node.js 中接收 buffer 数据时,需要以数组阵列的方式存储接收到的数据块,然后通过 Buffer.concat 对数组阵列进行合并,从而创建新的 ArrayBuffer(或 Buffer 对象)。这样即可正确接收并处理二进制数据。

Three.js 点阵数组传输示例

以下是具体的代码示例二:

以下以从后端传送 Three.js 中的点阵数组为例进行说明:

后端 Node.js 代码实现如下:


let buffer = Buffer.alloc((points.length + 4) * 4)

//points.length + 4:预留前四个数字为其他信息(比如两个数字为一组,或者三个数字为一组)
 
//预留位置
buffer.writeFloatLE(1, 0)
buffer.writeFloatLE(2, 4)
buffer.writeFloatLE(3, 8)
buffer.writeFloatLE(4, 12)

//buffer前四个数为信息
//point数据从第16位开始写入
for (let i = 0, len = points.length; i < len; i++) {
  buffer.writeFloatLE(points[i], i * 4 + 16)
}
res.send(buffer)

前端 JavaScript 代码实现如下:


let pointXhr = new XMLHttpRequest()
pointXhr.onreadystatechange = function () {
  var DONE = pointXhr.DONE || 4;
  if (pointXhr.readyState === DONE) {
    let buffer = pointXhr.response
    let bufferArray = new Float32Array(buffer);
    for (var i = 0; i < buffer.length; ++i) {
      bufferArray[i] = buffer[i];
    }
    let pointsArray = bufferArray.slice(4)
    let points = []
    //pointsArray 点阵从第5个开始(前四个数为其他信息)
    for (let i = 0, l = pointsArray.length / 3; i < l; i++) {
      points.push({
        x: pointsArray[i * 3],
        y: pointsArray[i * 3 + 1],
        z: pointsArray[i * 3 + 2]
      })
    }
    callback(points)
  }
}
pointXhr.open("POST",url,true);
pointXhr.responseType = 'arraybuffer';
pointXhr.send(null);

前端接收图片 Buffer 示例

此外,前端接收图片 Buffer 的方法也类似,具体代码如下:


let imageXhr = new XMLHttpRequest()
imageXhr.onreadystatechange = function () {
  var DONE = imageXhr.DONE || 4;
  if (imageXhr.readyState === DONE) {
    if (imageXhr.response) {
      let bufferArray = imageXhr.response
      let uint8Array = new Uint8Array(bufferArray);
      for (var i = 0; i < bufferArray.length; ++i) {
      uint8Array[i] = bufferArray[i];
    }
    callback(uint8Array)
    }
  }
}
imageXhr.open("POST",url,true);
imageXhr.responseType = 'arraybuffer';
imageXhr.send(null);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章