在 Koajs 中对 post 请求获取空 ctx.body

Getting empty ctx.body on post requests in Koajs

我是 Koa 新手。 我用它写了一个简单的 api 服务器。我使用了“koa-bodyparser”并且我在请求 header 中添加了 content-type: application/json,但我在 [=33= 上仍然收到空请求 body ] 要求。 有人可以指导我吗?

这是我的server.js

const Koa = require('koa');
const bodyParser = require('koa-bodyparser')();
const compress = require('koa-compress')();
const cors = require('@koa/cors')();
const helmet = require('koa-helmet')();
const logger = require('koa-logger')();

const errorHandler = require('./middleware/error.middleware');
const applyApiMiddleware = require('./api');
const { isDevelopment } = require('./config');
const db = require('./db/db');

const server = new Koa();

db.connectDB();

/**
 * Add here only development middlewares
 */
if (isDevelopment) {
  server.use(logger);
}

/**
 * Pass to our server instance middlewares
 */
server
  .use(errorHandler)
  .use(helmet)
  .use(compress)
  .use(cors)
  .use(bodyParser);

/**
 * Apply to our server the api router
 */
applyApiMiddleware(server);

module.exports = server;

这是我的终点:

router.post('/', controller.createOne);

和 createone 方法:

 exports.createOne = async ctx => {
 console.log(ctx.body);
 ctx.assert(username, 400, 'Username is required');
 ctx.assert(password, 400, 'Password is required')
 try {
   const { name, username, password } = ctx.request.body;

    let user = await User.findOne({ username });

    if (user){
      ctx.status = 400;
      ctx.body = { errors: [{ msg: 'User already exists' }] };
    }

    user = new User({
      name,
      username,
      password
    });

    const salt = await bcrypt.genSalt(10);

    user.password = await bcrypt.hash(password, salt);

    await user.save();

    user.password = undefined;

    ctx.status = 201;
    ctx.body = user;

  } catch (error) {
    console.error(error.message);
    ctx.status = 500;
    ctx.body = { errors: [{ msg: error.message }] }
 }
};

和 postman 请求:

你混淆了 ctx.bodyctx.request.body,至少在你的日志语句中(在解构赋值中它实际上是正确的)。

ctx.bodyctx.response.body 相同,它是 response 正文,它是空的,因为您尚未设置它。

ctx.request.body 是您真正想要的 request body。


我注意到的其他一些问题:

  • 您在 ctx.assert 行中使用了 usernamepassword,然后才定义它们。

  • 在您的重复用户案例中,您忘记了从您的函数中 return,因此该函数的其余部分仍将 运行,即使您将创建一个现有用户一个新的。


由于您似乎正在调试错误 500:一个小提示,error.message 对于调试来说毫无用处,因为它缺少堆栈(最重要的是 - 因为这就是显示的内容你错误的确切来源)和错误 class、代码和其他属性。如果您使用 console.error,请始终记录整个错误对象,而不仅仅是消息:console.error(error)。如果你想在前面加上一些文本,不要使用连接,而是使用单独的参数,所以对象仍然是格式化的:console.error('Error in request:', error).

如果你需要一个字符串(例如,当 return 将它作为响应时,顺便说一下,你应该只在开发模式下做,因为你不想暴露你的内心潜在攻击者的工作原理),请使用 error.stack 而不是 error.message,因为它将包含更多信息。