Node Express接收Apple Wallet Pass注册请求时req.body为undefined
问题根因
req.body返回undefined和Apple Wallet的请求逻辑无关,从你打印的请求头中content-length: '80'字段可以确认,请求已经正常携带了JSON载荷(包含你需要的pushToken)。问题出在Express框架的默认配置:Express 4.x及以上版本默认不会自动解析请求体,你没有注册对应的JSON解析中间件,框架不会把请求载荷解析挂载到req.body属性上。
修复方案
- 在所有路由定义之前,注册Express内置的JSON请求体解析中间件,注意顺序不能放反,中间件必须在路由之前注册才会对路由生效:
const express = require("express"); const app = express(); // 新增:JSON请求体解析中间件,必须写在路由注册前 app.use(express.json()); app.route( "/pass/:version/devices/:deviceLibraryIdentifier/registrations/:passTypeIdentifier/:serialNumber" ) .post(async (req, res) => { console.log("here! registration"); console.log("PARAMS", req.params); console.log("HEADERS", req.headers); console.log("BODY", req.body); // 解析成功后即可直接从req.body中取到pushToken字段 const { pushToken } = req.body; // 注意:按照Apple Wallet接口规范,首次注册成功需要返回201状态码,不要返回默认200 res.sendStatus(201); });
- 遵循Apple Wallet注册接口的状态码规范,避免Wallet判定注册失败反复重试:
- 设备首次注册当前通行证成功:返回
201 Created - 该设备已经注册过对应序列号的通行证:返回
200 OK - 请求头Authorization携带的token和你配置的authenticationToken不匹配:返回
401 Unauthorized
- 设备首次注册当前通行证成功:返回
兜底排查点
如果加完中间件还是无法读取请求体,按以下顺序排查:
- 确认中间件位置:
app.use(express.json())必须放在所有调用req.body的路由之前,放在路由后面不会生效 - 检查ngrok配置:默认
ngrok http命令会透传全部请求体,不要开启请求改写、body拦截类的自定义规则 - 不需要额外安装第三方
body-parser依赖,当前Express版本已经内置了JSON解析能力,混用旧版第三方解析包反而可能导致兼容问题
内容的提问来源于stack exchange,提问作者Jason Lee
相关产品推荐
相关产品推荐

