如何解析Content-Type为application/x-www-form-urlencoded的JSON请求体?
问题分析与解决方案
问题根源
对方发送的请求不符合标准application/x-www-form-urlencoded规范:正常该类型请求应为key=value的键值对格式,但对方直接将整个JSON字符串作为请求体内容发送,导致express的内置解析器无法正确识别,最终将整个JSON字符串解析为对象的键,值为空字符串。
解决方法
绕过express的内置表单解析器,直接读取原始请求体并手动解析JSON。以下提供两种可行实现方式:
方式1:手动监听数据流读取原始内容
const express = require('express'); const app = express(); app.post('/checkSupPay', (req, res) => { let rawData = ''; // 收集原始请求体数据 req.on('data', chunk => rawData += chunk.toString()); req.on('end', () => { try { // 清理可能存在的外层单引号(根据实际请求体调整) let cleanedBody = rawData.trim(); if (cleanedBody.startsWith("'") && cleanedBody.endsWith("'")) { cleanedBody = cleanedBody.slice(1, -1); } // 解析为JSON对象 const parsedBody = JSON.parse(cleanedBody); req.body = parsedBody; // 后续业务逻辑处理 console.log('解析后的请求体:', parsedBody); res.status(200).send('处理成功'); } catch (err) { console.error('请求体解析失败:', err); res.status(400).send('无效的请求体格式'); } }); }); app.listen(3000, () => console.log('服务启动'));
方式2:使用body-parser的raw中间件
借助body-parser的raw中间件直接获取原始请求体缓冲区,再转为字符串处理:
const express = require('express'); const bodyParser = require('body-parser'); const app = express(); // 仅针对目标路由使用raw中间件,指定匹配的Content-Type app.post('/checkSupPay', bodyParser.raw({ type: 'application/x-www-form-urlencoded' }), (req, res) => { try { let rawBody = req.body.toString().trim(); // 清理多余外层引号 if (rawBody.startsWith("'") && rawBody.endsWith("'")) { rawBody = rawBody.slice(1, -1); } const parsedBody = JSON.parse(rawBody); // 业务逻辑处理 console.log('解析成功:', parsedBody); res.sendStatus(200); } catch (err) { console.error('解析失败:', err); res.sendStatus(400); } }); app.listen(3000, () => console.log('服务启动'));
为什么之前的配置无效
express.urlencoded:仅能解析key=value格式的表单数据,无法识别无键的纯JSON字符串。express.json:默认仅处理Content-Type: application/json的请求,即使强制指定type,若请求体存在额外包裹(如单引号),也会导致解析失败。
内容的提问来源于stack exchange,提问作者Sergii Rubicon
相关产品推荐
相关产品推荐

