Flutter、NodeJS及Cloud Functions间传JSON含重音字符时云函数解析报错咨询
问题根因定位
逐链路校验后,3个叠加配置错误直接触发了带重音字符的解析故障,纯英文字符场景下不会暴露问题:
- NodeJS转发端Content-Length计算逻辑错误
JS字符串的.length属性统计的是UTF-16码元个数,并非UTF-8编码下的实际字节长度。像é、à这类带重音的拉丁字符,在UTF-8编码下占2个字节,但在JS字符串中仅算1个长度单位。用字符串长度作为Content-Length值发送请求时,带多字节字符的请求体会被对端服务按Header声明的长度截断,最终出现“JSON不完整、意外结束”的解析错误。纯英文字符都是单字节,字符串长度和实际字节数完全一致,因此不会触发截断问题。 - NodeJS转发端Content-Type拼写错误
代码中请求头写的是application/application-json,属于多写了一层application字段,正确值应为application/json。这个错误会导致Cloud Function侧的express.json()中间件无法匹配到正确的请求体类型,自动解析逻辑完全不生效,req.body会保持为原始Buffer流状态,不会自动转换为JSON对象。 - Cloud Function端解析逻辑冗余错误
代码已经通过app.use(express.json())挂载了内置JSON解析中间件,只要Content-Type配置正确,中间件会自动完成请求体解析,不需要再手动执行JSON.parse(req.body)。当前场景下因为前两个错误导致中间件未触发解析,req.body是Buffer类型,直接传入JSON.parse会触发类型转换异常,最终落到catch分支报出解析错误。
逐环节修复方案
NodeJS转发端配置修正
- 修正Content-Length计算逻辑,用UTF-8编码后的真实Buffer字节数替代字符串长度计算
- 修正Content-Type拼写错误,去掉冗余的自定义charset Header(
application/json默认编码即为UTF-8,自定义charset字段不会被所有中间件正确识别) - 发送请求时直接写入UTF-8 Buffer,避免二次编码导致的长度错位
修正后的转发代码参考:
const CFSdata = JSON.stringify({'order': data}) console.log(CFSdata); const CFSBuffer = Buffer.from(CFSdata, 'utf8'); const optionsCFS = { hostname: process.env.CLOUD_URL, port: 443, timeout: 5000, path: process.env.CLOUD_ORDER_SAVE_PATH, method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': CFSBuffer.length } } const orderReq = https.request(optionsCFS, resCFServer => { if (resCFServer.statusCode == 200) { // 成功处理逻辑 } }) orderReq.write(CFSBuffer); orderReq.end();
Cloud Function端逻辑修正
- 保留express.json()中间件配置,去掉冗余的手动JSON.parse逻辑。中间件会自动完成请求体解析,解析失败时会直接返回400状态码,不需要重复写try/catch判断
- 按需调整中间件的请求体大小限制,避免大订单被截断
修正后的函数代码参考:
const express = require("express"); const app = express(); app.use(express.json({ limit: '10mb' })); exports.saveOrder = functions.https.onRequest(async (req, res) => { console.log('-------------saveOrder Triggered----------------') // req.body已由中间件解析为JS对象,无需手动parse const order = req.body?.order; if (!order) { return res.sendStatus(400); } // 后续订单持久化逻辑 })
验证步骤
修复后做两组对照测试即可确认修复效果:
- 构造包含
é、à等带重音字符的测试订单(如餐厅名称设为Café de Paris),走全链路触发请求,检查Cloud Function控制台是否能完整打印解析后的订单数据,无截断、无解析异常 - 保留原有纯英文订单做回归测试,确认普通场景下的请求流程不受影响
内容的提问来源于stack exchange,提问作者Damandroid
相关产品推荐
相关产品推荐

