Express 4.18中如何为单个路由覆盖全局body parser?
问题描述
使用Express 4.18开发应用时,全局配置了JSON格式的body parser,但希望为单个/webhook路由改用raw解析器。尝试多种配置后,JSON解析始终优先生效,移除全局JSON解析器后,/webhook路由的req.body能正常变为Buffer类型,但应用有数十个路由,不想逐个配置解析器以减少bug风险,询问是否可实现单个路由覆盖全局body parser。
示例代码:
var express = require('express') var app = express() // 全局应用json解析器 app.use(express.json()) // 该路由使用全局json解析器 app.post('/login', function (req, res) { // req.body 是解析后的JSON对象,符合预期 }) // 试图为该端点覆盖全局json解析器 app.post('/webhook', express.raw({type: "application/json"}), function (req, res) { // req.body 仍然是解析后的JSON对象,而非Buffer })
解决方案
有两种可行的方法实现单个路由覆盖全局body parser:
方法一:调整中间件注册顺序
Express中间件按注册顺序执行,因此先注册需要raw解析的/webhook路由,再全局注册JSON解析器。当请求到达/webhook时,raw解析器会先处理请求,后续的全局JSON解析器不会重复解析已处理过的请求(因为req.body已存在时,默认的express.json()不会再次解析)。
修改后的代码:
var express = require('express') var app = express() // 先注册需要raw解析的路由 app.post('/webhook', express.raw({type: "application/json"}), function (req, res) { // req.body 现在是 Buffer 类型 }) // 全局应用json解析器,对其他路由生效 app.use(express.json()) // 其他路由正常使用全局json解析 app.post('/login', function (req, res) { // req.body 是解析后的JSON对象 })
方法二:在全局JSON解析器中添加排除逻辑
如果无法调整路由注册顺序,可以给全局的JSON解析器添加条件判断,当请求路径为/webhook且请求方法为POST时,跳过JSON解析。
修改后的代码:
var express = require('express') var app = express() // 全局json解析器,排除/webhook路由 app.use(function(req, res, next) { if (req.path === '/webhook' && req.method === 'POST') { return next() } express.json()(req, res, next) }) // /login路由正常使用全局json解析 app.post('/login', function (req, res) { // req.body 是解析后的JSON对象 }) // /webhook路由单独使用raw解析 app.post('/webhook', express.raw({type: "application/json"}), function (req, res) { // req.body 现在是 Buffer 类型 })
两种方法都能满足需求,方法一更简洁直观,方法二适合路由顺序无法调整的场景。
内容的提问来源于stack exchange,提问作者CaffeineFueled
相关产品推荐
相关产品推荐

