Nuxt.js Server Middleware如何接收XML数据

9次阅读

nuxt.js 的 servermiddleware 默认不解析 xml,需手动读取原始请求流并用 fast-xml-parser 解析;nitro 下推荐使用 readrawbody,nuxt 2 则需监听 data/end 事件

Nuxt.js Server Middleware如何接收XML数据

Server Middleware 默认不解析 XML

Nuxt.jsserverMiddleware 运行在 Node.js 服务端(如 nitro 或旧版 connect),但默认只自动解析 application/jsonapplication/x-www-form-urlencoded,对 application/xmltext/xml 完全忽略 —— 所以你直接读 req.body 会是 undefined

必须手动读取原始请求流并解析 XML

你需要:① 阻止 body-parser 提前消费流(尤其在 Nitro 环境下);② 用 stream.Readable 读取原始 req;③ 选一个轻量 XML 解析器。推荐用 fast-xml-parser(无依赖、支持流式 buffer 输入)。

  • 安装:npm install fast-xml-parser
  • Nitro 中需禁用默认解析:在 serverMiddleware 函数开头加 req.rawBody = true(仅 Nitro 有效)或手动接管流
  • 注意:不能在中间件里调用 req.pipe() 多次,流只能消费一次
import { XMLParser } from 'fast-xml-parser';  export default defineEventHandler(async (event) => {   const contentType = event.req.headers['content-type'] || '';   if (!contentType.includes('xml')) {     return createError({ statusCode: 400, statusMessage: 'Content-Type must be XML' });   }    // 读取原始 body   const rawBody = await readRawBody(event);      try {     const parser = new XMLParser({ ignoreAttributes: false, ignoreDeclaration: true });     const result = parser.parse(rawBody);     event.context.xmlPayload = result;   } catch (e) {     return createError({ statusCode: 400, statusMessage: 'Invalid XML' });   } });

readRawBody 是 Nitro 提供的安全读取方式

在 Nuxt 3 + Nitro 下,readRawBody(event) 是唯一推荐的原始体读取方法。它已处理了编码、超时、大小限制等边界问题。不要用 req.on('data') 手动拼接 —— 容易丢数据或阻塞事件循环

  • readRawBody 返回 promise<String buffer></string>,默认返回字符串;传 { encoding: NULL } 可得 Buffer
  • 若 XML 含非 UTF-8 编码(如 ISO-8859-1),需先按对应编码解码 Buffer,再传给 XML 解析器
  • Nitro 默认限制 body 最大为 1MB,如需更大,改 nitro.config.ts 中的 runtimeConfig.bodySizeLimit

兼容旧版 Nuxt 2(express/Connect 中间件)

如果你还在用 Nuxt 2,serverMiddleware 是标准 Express 中间件函数,需手动监听 dataend 事件:

const { XMLParser } = require('fast-xml-parser');  export default function xmlMiddleware(req, res, next) {   if (!req.headers['content-type']?.includes('xml')) return next();    let data = '';   req.setEncoding('utf8');   req.on('data', chunk => { data += chunk; });   req.on('end', () => {     try {       const parser = new XMLParser();       req.xmlBody = parser.parse(data);       next();     } catch (e) {       res.status(400).json({ error: 'Invalid XML' });     }   }); }

注意:这里没做流错误监听(req.on('error')),线上必须补上,否则连接异常会导致请求挂起。

XML 解析本身不难,真正容易出问题的是流控制时机和编码一致性 —— 特别是当客户端发来带 bom 的 UTF-8 XML 或混合编码声明时,fast-xml-parser 默认不处理 BOM,需要提前 strip。

text=ZqhQzanResources