在 Koajs 中发布请求时获取空 ctx.body
我是 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 }] }
}
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您将
ctx.body
与ctx.request.body
混淆了,至少在您的日志语句中(在解构赋值中它实际上是正确的)。ctx.body
与ctx.response.body
相同,它是 response body,它是空的,因为您还没有设置它。ctx.request.body
是您实际想要的请求正文。我注意到的其他一些问题:
在定义这些
ctx.assert
行之前,您使用了username
和password
。在重复的用户案例中,您忘记从函数返回,因此函数的其余部分仍将运行,即使对于现有用户,您也将创建一个新用户。
由于您似乎正在调试错误 500:一个小提示,
error.message
对于调试来说非常无用,因为它缺少堆栈(最重要的是 - 因为这显示了您在哪里错误的确切来源)以及错误类、代码和其他属性。如果您使用console.error,请始终记录整个错误对象,而不仅仅是消息:console.error(error)。如果您想在前面添加一些文本,请不要使用串联,而应使用单独的参数,因此对象的格式仍为:console.error('Error in request:', error)
。如果您需要一个字符串(例如,当将其作为响应返回时,您应该只在开发模式下执行此操作,因为您不想将内部工作暴露给潜在的攻击者),请使用
error .stack
而不是error.message
,因为它将包含更多信息。You are confusing
ctx.body
withctx.request.body
, at least in your log statement (in the destructured assignment it is actually correct).ctx.body
is the same asctx.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
andpassword
in thosectx.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 useconsole.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 noterror.message
, because it will contain a lot more information.