错误:在使用koa发送它们后无法设置标题
问题描述:
Stack Overflow有很多关于此错误的问题。每个人都有其背景。我曾尝试应用大多数建议的解决方案,但都没有工作。我也是新来KOA和猫鼬错误:在使用koa发送它们后无法设置标题
"use strict"
const Koa = require('koa')
const Router = require('koa-router')
const router = new Router()
const mongoose = require('mongoose')
const Pug = require('koa-pug')
const app = new Koa()
const KoaBody = require('koa-body')
const koaBody = new KoaBody()
mongoose.Promise = global.Promise
mongoose.connect('mongodb://localhost/my_db', {useMongoClient: true, promiseLibrary: global.Promise})
const personSchema = mongoose.Schema({
name: String,
age: Number,
nationality: String
})
const Person = mongoose.model("Person", personSchema)
const pug = new Pug({
viewPath: '.',
})
router.get('/person', async ctx => {
ctx.render('person')
})
router.post('/person', koaBody, async (ctx, next) => {
const personInfo = ctx.request.body
if (!personInfo.name || !personInfo.age || !personInfo.nationality) {
return ctx.render('show_message', {message: "Sorry, you provided wrong info", type: "error"})
}
else {
const newPerson = new Person({
name: personInfo.name,
age: personInfo.age,
nationality: personInfo.nationality
})
if (ctx.response.headerSent) console.log("sent 0")
newPerson.save(function (err) {
if (ctx.response.headerSent) console.log("sent 1")
if (err) {
return err
}
else {
if (ctx.response.headerSent) console.log("sent 2")
ctx.response.flushHeaders()
ctx.render('show_message', {
message: "New person added", type: "success", person: personInfo
})
}
})
}
})
pug.use(app)
app.use(router.routes())
app.listen(3000,() => {
console.log("We are listening for connections on the server")
})
当我执行的代码,我收到以下错误:
We are listening for connections on the server
sent 1
sent 2
events.js:182
throw er; // Unhandled 'error' event
^
Error: Can't set headers after they are sent.
at validateHeader (_http_outgoing.js:504:11)
at ServerResponse.setHeader (_http_outgoing.js:511:3)
at Object.set (C:\Users\nahas\OneDrive\Code\Javascript\Node Modules\node_modules\koa\lib\response.js:440:16)
at Object.set type [as type] (C:\Users\nahas\OneDrive\Code\Javascript\Node Modules\node_modules\koa\lib\response.js:310:12)
at Object.type (C:\Users\nahas\OneDrive\Code\Javascript\Node Modules\node_modules\delegates\index.js:92:31)
at Object.contextRenderer [as render] (C:\Users\nahas\OneDrive\Code\Javascript\Node Modules\node_modules\koa-pug\src\pug.js:107:15)
at C:\Users\nahas\OneDrive\Code\Javascript\Node Modules\learn-koa\app.js:49:25
at C:\Users\nahas\OneDrive\Code\Javascript\Node Modules\node_modules\mongoose\lib\model.js:3835:16
at C:\Users\nahas\OneDrive\Code\Javascript\Node Modules\node_modules\mongoose\lib\services\model\applyHooks.js:162:20
at _combinedTickCallback (internal/process/next_tick.js:95:7)
at process._tickCallback (internal/process/next_tick.js:161:9)
我试图找出通过登录控制台的确切位置的头被送到时,他们被发送。正如你可以从错误的输出看到的,头被这条线后,立即派:
newPerson.save(function (err) {
这意味着猫鼬保存功能发送头给用户。 如何解决这个问题?
答
newPerson.save()
是一个异步功能。将保存操作完成时调用的回调函数传递给它。然而,当它被调用时,你的路由器功能已经返回,所以已经发送的头文件。
这就是异步/等待模式进场的地方。由于您已经在异步功能中,所以您只需要等待.save()
的结果。你可以等待承诺。幸运的是,如果你没有传递回调,mongoose .save()会返回一个承诺。这意味着你可以等待它。所以......使用异步时
await newPerson.save()
ctx.render('show_message', {
message: "New person added", type: "success", person: personInfo
})
错误处理做了一些不同的等待,或更好的错误处理再次得当;-)。
您将使用try/catch来进行错误处理,正如您在js中通常那样。
try{
await newPerson.save()
ctx.render(...)
}catch(err){
ctx.status=500
ctx.body="somthing went wrong"
}
It Worked !!非常感谢Will。你是一个救世主。我几乎放弃了猫鼬,直接与Mongodb打交道...... –