如何在Express中解析POST请求里赋值给变量的JSON数据
Express处理非标准JSON格式Webhook请求的解决方案
对方发送的请求虽然声明了content-type: application/json,但实际内容是带data=前缀的非标准JSON格式,express.json()会严格校验JSON格式合法性,不符合就会抛出解析错误,无法正常挂载req.body。
方案1:单独为Webhook路由配置特殊解析(推荐)
不对应用全局的express.json(),仅针对该支付Webhook路由单独获取原始请求体预处理,不会影响其他正常接口的解析逻辑:
// 该路由不要走全局的express.json(),单独配置raw中间件获取原始请求体 app.post('/payment/webhook', express.raw({ type: 'application/json' }), (req, res) => { try { // 把Buffer格式的原始请求体转成字符串 const rawBody = req.body.toString(); // 去掉开头的data=前缀,拿到标准JSON字符串 const jsonStr = rawBody.replace(/^data=/, ''); // 自行解析得到标准JS对象 const payload = JSON.parse(jsonStr); // 后续正常处理业务逻辑,比如读取订单信息 console.log(payload.return.orders); // 按服务商要求返回成功状态 res.sendStatus(200); } catch (err) { console.error('Webhook请求解析失败:', err); // 解析失败返回对应错误状态 res.sendStatus(400); } });
方案2:全局解析失败后兜底处理
如果已经全局配置了express.json()不想修改路由结构,可以通过添加解析错误兜底逻辑处理:
- 先修改全局
express.json()配置,提前留存原始请求体:
app.use(express.json({ verify: (req, res, buf) => { // 把原始请求体字符串挂载到req上供后续兜底使用 req.rawBody = buf.toString(); } }));
- 在所有路由之后添加全局错误处理中间件,捕获JSON解析失败的场景单独处理Webhook请求:
app.use((err, req, res, next) => { // 仅处理JSON解析错误、且是支付Webhook路径的请求 if (err.type === 'entity.parse.failed' && req.path === '/payment/webhook') { try { const jsonStr = req.rawBody.replace(/^data=/, ''); req.body = JSON.parse(jsonStr); // 解析成功后继续走后续路由逻辑 return next(); } catch (parseErr) { return res.sendStatus(400); } } // 其他错误正常透传 next(err); });
注意事项
- 所有JSON解析操作必须包裹
try/catch,避免异常输入导致服务崩溃 - 替换
data=前缀时可增加合法性校验,仅对匹配前缀的内容做处理,避免误修改正常JSON请求 - 处理完业务逻辑后必须按照支付服务商的要求返回对应状态码,避免服务商反复推送重复通知
内容的提问来源于stack exchange,提问作者jurordrained
相关产品推荐
相关产品推荐

