如何从Node.js/Electron服务器的POST请求中提取XML数据
解决Node.js/Electron服务器提取ANPR摄像头POST请求中的XML内容问题
你遇到的问题很典型——IP摄像头发送的POST请求是multipart/form-data格式,里面混合了XML文本和图片二进制数据,直接把整个请求体转成字符串肯定没法直接拿到干净的XML。我来给你捋捋怎么解决:
核心问题:请求是多部分表单格式
你现在的代码把所有请求数据拼接成一个字符串,里面包含了表单分隔符、每个字段的头信息(比如Content-Disposition)、XML内容和图片二进制数据,自然没法直接提取XML。手动解析这种格式容易出错,最好用成熟的库来处理。
推荐方案:用busboy解析多部分请求
busboy是专门处理multipart/form-data的轻量库,非常适合Node.js原生HTTP服务器场景。
第一步:安装依赖
先在项目里安装busboy:
npm install busboy
第二步:修改你的服务器代码
把原来的代码改成用busboy来解析请求,精准提取anpr.xml字段的内容:
const http = require('http'); const Busboy = require('busboy'); const port = 7200; http.createServer((req, res) => { // 只处理POST类型的多部分表单请求 if (req.method !== 'POST' || !req.headers['content-type']?.includes('multipart/form-data')) { res.writeHead(400); return res.end('仅接受multipart/form-data格式的POST请求'); } // 初始化busboy,传入请求头来识别分隔符 const busboy = Busboy({ headers: req.headers }); // 监听文件/字段事件,找到我们需要的anpr.xml busboy.on('file', (fieldname, file, filename, encoding, mimetype) => { // 只处理名为anpr.xml的XML文件 if (fieldname === 'anpr.xml' && mimetype === 'text/xml') { let xmlContent = ''; // 读取XML的每一段内容 file.on('data', (chunk) => { xmlContent += chunk.toString(); }); // 读取完成后,就可以处理XML了 file.on('end', () => { console.log('提取到的干净XML:', xmlContent); // 这里可以添加你的XML解析逻辑,比如转成JSON或者提取车牌信息 }); } else { // 跳过其他二进制内容(比如图片),避免占用内存 file.resume(); } }); // 所有字段解析完成后,返回响应 busboy.on('finish', () => { res.writeHead(200, { 'Connection': 'close' }); res.end('请求处理完成'); }); // 处理解析过程中的错误 busboy.on('error', (err) => { console.error('解析请求出错:', err); res.writeHead(500); res.end('服务器内部错误'); }); // 将请求流交给busboy处理 req.pipe(busboy); // 监听请求自身的错误 req.on('error', (err) => { console.error('请求异常:', err); }); }).listen(port); console.log(`服务器在端口${port}监听中`);
第三步:可选:把XML转成JSON方便处理
如果需要把XML解析成JavaScript对象,可以用xml2js库:
npm install xml2js
然后在XML读取完成的回调里添加解析代码:
const xml2js = require('xml2js'); // ... 前面的代码 ... file.on('end', () => { console.log('提取到的XML:', xmlContent); // 初始化解析器,explicitArray设为false避免把单个节点转成数组 const parser = new xml2js.Parser({ explicitArray: false }); parser.parseString(xmlContent, (err, parsedResult) => { if (err) { console.error('解析XML失败:', err); return; } // 现在你可以轻松获取车牌等信息了 const licensePlate = parsedResult.EventNotificationAlert.ANPR.licensePlate; console.log('识别到的车牌:', licensePlate); }); });
如果你不想用第三方库(不推荐)
手动解析的话,你需要先从请求头里拿到分隔符(比如boundary=-------------------------7e13971310878),然后把整个请求体按分隔符拆分,找到包含anpr.xml的块,再去掉块里的头信息,提取后面的XML内容。但这种方式要处理各种边界情况(比如编码、换行、Content-Length不匹配等),很容易出问题,所以还是推荐用busboy这种成熟的库。
内容的提问来源于stack exchange,提问作者Ryan Williams
相关产品推荐
相关产品推荐

