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

Server Middleware 默认不解析 XML
Nuxt.js 的 serverMiddleware 运行在 Node.js 服务端(如 nitro 或旧版 connect),但默认只自动解析 application/json 和 application/x-www-form-urlencoded,对 application/xml 或 text/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 中间件函数,需手动监听 data 和 end 事件:
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。