在 Koajs 中发布请求时获取空 ctx.body

发布于 2025-01-20 10:24:37 字数 2060 浏览 3 评论 0原文

我是 Koa 的新手。 我用它写了一个简单的 api 服务器。我使用了“koa-bodyparser”,并且已将 content-type: application/json 添加到请求标头,但我仍然在发布请求时收到空请求正文。 有人可以指导我吗?

这是我的 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 }] }
 }
};

和邮递员请求: 输入图片此处描述

I'm new to Koa.
I wrote a simple api server with it. I have used "koa-bodyparser" and i have added content-type: application/json to the request header, but i still get empty request body on post requests.
Could anyone please guide me?

this is my 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;

and this is my endpoint:

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

and the createone method:

 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 }] }
 }
};

and the postman request:
enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

亽野灬性zι浪 2025-01-27 10:24:37

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

ctx.bodyctx.response.body 相同,它是 response body,它是空的,因为您还没有设置它。

ctx.request.body 是您实际想要的请求正文。


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

  • 在定义这些 ctx.assert 行之前,您使用了 usernamepassword

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


由于您似乎正在调试错误 500:一个小提示,error.message 对于调试来说非常无用,因为它缺少堆栈(最重要的是 - 因为这显示了您在哪里错误的确切来源)以及错误类、代码和其他属性。如果您使用console.error,请始终记录整个错误对象,而不仅仅是消息:console.error(error)。如果您想在前面添加一些文本,请不要使用串联,而应使用单独的参数,因此对象的格式仍为:console.error('Error in request:', error)

如果您需要一个字符串(例如,当将其作为响应返回时,您应该只在开发模式下执行此操作,因为您不想将内部工作暴露给潜在的攻击者),请使用 error .stack 而不是error.message,因为它将包含更多信息。

You are confusing ctx.body with ctx.request.body, at least in your log statement (in the destructured assignment it is actually correct).

ctx.body is the same as ctx.response.body, it's the response body which is empty because you didn't set it yet.

ctx.request.body is the request body which you actually want.


Some other issues I noticed:

  • You use username and password in those ctx.assert lines before they are defined.

  • In your duplicate user case, you forgot to return from your function, so the rest of the function will still run and even with an existing user you will create a new one.


Since you seem to be working on debugging that error 500: A little tip, error.message is quite useless for debugging as it's missing the stack (most importantly - since this is what shows you where exactly the error came from) and the error class, code and other properties. If you use console.error, always log the whole error object and not just the message: console.error(error). If you want to prepend some text, don't use concatenation, use separate arguments instead, so the object is still formatted: console.error('Error in request:', error).

If you need a string (for example when returning it as response, which you should do only in development mode by the way because you don't want to expose your inner workings to potential attackers), use error.stack and not error.message, because it will contain a lot more information.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文