【问题标题】:express app not giving any response but the data is saved to mongodb. ERR_HTTP_HEADERS_SENTexpress 应用程序没有给出任何响应,但数据已保存到 mongodb。 ERR_HTTP_HEADERS_SENT
【发布时间】:2021-08-17 15:04:20
【问题描述】:

我仍在学习 MERN 堆栈,并且正在使用 MERN 堆栈制作一个简单的 CRUD 应用程序。我为请求添加了一些使用 express-validator 的验证器。问题是,数据以某种方式发送并保存到数据库中,但当我使用 Postman 尝试时没有给出任何响应。

我认为问题在于后控制器功能或验证器的响应。我不知道它到底在哪里。我被困在这里差不多一个小时了。已经来回在谷歌上得到一些答案。但找不到任何。 这是代码。

index.js:

import express from 'express'
import mongoose from 'mongoose'
import dotenv from 'dotenv'

import { router as postRoutes } from './routes/post.js'
import { router as authRoutes } from './routes/auth.js'

//setup
const app = express()
app.use(express.json());
dotenv.config();

app.use((req, res, next) => {
    res.setHeader('Access-Control-Allow-Origin','*')
    res.setHeader('Access-Control-Allow-Methods','POST, GET, PUT, DELETE, OPTIONS')
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type')
    next();
})

//route groups
app.use('/v1/post', postRoutes)
app.use('/v1/auth', authRoutes)

//validation
app.use((error,req,res,next) => {
    const status = error.errStatus || 500
    const message = error.message
    const data = error.data
    res.status(status).json({message : message, data: data})
})

//connect to mongodb
mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true })
.then(app.listen(4000, ()=>{ console.log('Server is up!')}))
.catch(err => console.log(err))

后控制器: *注意:这里我不发送post控制器的全部代码,只发送create post函数

import { validationResult } from 'express-validator'
import PostSchema from '../models/post.js'

//handle post requests
const createPost = (req, res, next) => {
    const title = req.body.title
    const content = req.body.content
    //get errors result from express-validator
    const errors =  validationResult(req)
    if(!errors.isEmpty()){
       const err = new Error('Invalid request')
       err.errStatus = 400
       err.data = errors.array()
       throw err
    }

    const Posts = new PostSchema({
        title: title,
        content: content,
        author: {
            _id: 1,
            name: 'fratio '
        }
    })
    
    Posts.save()
    .then(result =>{
        res.status(201).json({ //the error messsage says there is an error on this line
            description: "successfully created",
            data : result,
        })
    })
    .catch(err =>console.log(err))
    next()
}

export {createPost}

发布路线:

import express from 'express'
import { body } from 'express-validator'
import { createPost, deletePost, getPosts, updatePost } from '../controllers/post.js'

const router = express.Router()

router.get('/', getPosts)
router.post('/create',
    [
        body('title').isLength({min: 5}).withMessage('minimum length is 5 characters'), 
        body('content').isLength({min: 5}).withMessage('minimum length is 5 characters')
    ],  createPost)
router.put('/:id/update', updatePost)
router.delete('/:id/delete', deletePost)

export  { router }

发布架构:

import mongoose from 'mongoose'

const Schema = mongoose.Schema
const PostSchema = new Schema({
    title: {
        type : String,
        required : true,
    },
    content: {
        type : String,
        required : true
    },
    author: {
        type: Object,
        required: true
    }
},{
    timestamp: true
})

export default  mongoose.model("PostSchema", PostSchema) 

错误信息:

[nodemon] starting `node index.js`
Server is up!
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:561:11)
    at ServerResponse.header (D:\Programming\Web Development\mern-playground\mern-basic-1\server\node_modules\express\lib\response.js:771:10)
    at ServerResponse.send (D:\Programming\Web Development\mern-playground\mern-basic-1\server\node_modules\express\lib\response.js:170:12)
    at ServerResponse.json (D:\Programming\Web Development\mern-playground\mern-basic-1\server\node_modules\express\lib\response.js:267:15)
    at file:///D:/Programming/Web%20Development/mern-playground/mern-basic-1/server/controllers/post.js:28:25
    at processTicksAndRejections (internal/process/task_queues.js:95:5) {
  code: 'ERR_HTTP_HEADERS_SENT'
}

非常感谢。希望大家帮帮我,我真的不知道如何解决这个问题。如果代码难以阅读,请见谅。

【问题讨论】:

    标签: javascript node.js mongodb express mongoose


    【解决方案1】:

    你的承诺逻辑有问题。

    const createPost = (req, res, next) => {
        
        // This will create a promise, when the promise is resolved "then" will be executed
        // if the promise is rejected, "catch" will be executed.
        // A promise doesn't actually stops the flow of the code here, "next()" will be called
        // before the promise is resolved/rejected
        Posts.save()
        .then(result =>{
            res.status(201).json({ //the error messsage says there is an error on this line
                description: "successfully created",
                data : result,
            })
        })
        .catch(err =>console.log(err));
    
        // "next" is called right after the promise is created
        // but the promise doesn't stop the flow of the code
        // so this is executed while the promise is still being resolved/reject
        next()
    }
    

    你在 promise 被解析/拒绝之前调用 next ,所以下一个处理程序可能是 express 的默认 404 处理程序,这就是你将收到的响应。稍后,promise 将被解析/拒绝,您将尝试再次发送响应,这就是引发错误的原因。

    解决方案很简单,将 next() 调用移到你的 Promise 中或删除它。

    【讨论】:

    • 工作完美,你帮了我很多。非常感谢!
    猜你喜欢
    • 2012-10-23
    • 1970-01-01
    • 2012-06-04
    • 1970-01-01
    • 2020-10-15
    • 2021-11-04
    • 2022-01-04
    • 1970-01-01
    • 2021-06-27
    相关资源
    最近更新 更多