You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript Express使用内置解析器时req.body为undefined如何解决?

问题现象

开发TypeScript API时,使用Express内置的默认解析器获取请求体时,得到的req.body值为undefined。使用已废弃的body-parser库作为POST路由中间件可以得到预期结果,需要找合规的替代方案。


初始错误代码

入口代码

import express from 'express';
import { router } from './routes';

const app = express();
const port = 3000;

app.use(router);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

app.listen(port, () => {
  console.log(`App rodando na porta: ${port}`);
});

路由代码

// import bodyParser from 'body-parser';
import express from 'express';
import { createUserService } from '../service';

export const router = express.Router();

router.post('/users', async (req, res) => {
  try {
    const { name, email, password } = req.body;
    await createUserService({ name, email, password });
    res.status(201).send({ name, email, password }).status(201);
  } catch (error) {
    res.status(400).send({ error: error.message });
  }
});

问题原因

Express中间件的执行顺序和注册顺序完全一致,初始代码中将请求体解析中间件注册在了路由之后,请求到达时会先进入路由处理逻辑,此时解析中间件还未执行,所以req.body为undefined。
无需使用废弃的body-parser,Express v4.16.0之后已经内置了express.json()和express.urlencoded()两个解析中间件,功能和body-parser完全一致。


解决方案

两种注册方式二选一即可:

方案1:调整全局中间件注册顺序,将解析中间件放在路由之前

修改入口代码如下:

import express from 'express';
import { router } from './routes';

const app = express();
const port = 3000;

// 先注册解析中间件
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// 再注册路由
app.use(router);

app.listen(port, () => {
  console.log(`App rodando na porta: ${port}`);
});

方案2:在路由内部单独注册解析中间件

适合仅需要给部分路由开启请求体解析的场景:

路由代码

import express from 'express';
import { createUserService } from '../service';

const router = express.Router();

// 路由内注册解析中间件
router.use(express.json());
router.use(express.urlencoded({ extended: true }));

router.post('/users', async (req, res) => {
  try {
    const { name, email, password } = req.body;
    await createUserService({ name, email, password });
    res.status(201).send({ name, email, password }).status(201);
  } catch (error) {
    res.status(400).send({ error: error.message });
  }
});

export { router };

入口代码

import express from 'express';
import { router } from './routes';

const app = express();
const port = 3000;

app.use(router);
app.listen(port, () => {
  console.log(`App rodando na porta: ${port}`);
});

内容的提问来源于stack exchange,提问作者Diego

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 09:57:02