Image missing with an Error: Cannot set header after they are sent to client

Image missing with an Error: Cannot set header after they are sent to client

我通过分离模型、视图和控制,将我的旧 Demo 项目转换为 MVC 风格,添加了一个新的控制器文件夹。除了存储图像外,所有功能都运行良好。我收到一个错误:Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

我做了一些调试并发现 图像在验证期间存在,但在发送到请求处理程序时不存在存储数据库 object。 Please check this image of debugging output

数据库中还有一个奇怪的错误。 title, body & image path 被插入数据库中两次。我删除了旧的东西并一次又一次地尝试。但仍然注意到,对于使用 '/posts/new' 页面的一次插入:两个相同的 objects 被存储在 mongodb 中。 Image attached from Mongo DB compass

项目流程如下:带有图像的请求 object 从“/posts/new”页面中选取,在验证中间件中进行验证,如果存在标题和图像:将发送到请求处理程序app.post('/posts/store', storePostController);,它将使用路径存储图像&它将存储一个mongo数据库文档,其中包含数据库中的标题、body和图像路径。

以下代码如下: 1) createPost.ejs

<!DOCTYPE html>
<html lang="en">
<!-- Header-->
<%- include('layouts/header'); -%>

    <body>
        <!-- Navigation-->
        <%- include('layouts/navbar'); -%>
            <!-- Page Header-->
            <header class="masthead" style="background-image: url('/assets/img/contact-bg.jpg')">
                <div class="container position-relative px-4 px-lg-5">
                    <div class="row gx-4 gx-lg-5 justify-content-center">
                        <div class="col-md-10 col-lg-8 col-xl-7">
                            <div class="page-heading">
                                <h1>Create New Post</h1>
                            </div>
                        </div>
                    </div>
                </div>
            </header>
            <!-- Main Content-->
            <main class="mb-4">
                <div class="container px-4 px-lg-5">
                    <div class="row gx-4 gx-lg-5 justify-content-center">
                        <div class="col-md-10 col-lg-8 col-xl-7">
                            <div class="my-5">
                                <form action="/posts/store" method="POST" enctype="multipart/form-data">
                                    <div class="form-floating">
                                        <input class="form-control" id="title" name="title" type="text"
                                            placeholder="Enter the title..." />
                                        <label for="title">Title</label>
                                    </div>

                                    <div class="form-floating">
                                        <textarea class="form-control" id="body" name="body" style="height: 12rem"
                                            placeholder="Enter your message here..." style="height: 12rem"></textarea>
                                        <label for="message">Description</label>
                                    </div>

                                    <div class="form-floating">
                                        <input class="form-control" id="image" name="image" type="file"
                                            placeholder="Upload an image" />
                                        <label for="title">Image</label>
                                    </div>

                                    <!-- Submit Button-->
                                    <button id="submitButton" type="submit">Send</button>
                                </form>
                            </div>
                        </div>
                    </div>
                </div>
            </main>
            <!-- Footer-->
            <%- include('layouts/footer'); -%>
                <!-- Scripts-->
                <%- include('layouts/scripts'); -%>
    </body>

</html>

2) index.js

const express = require('express');
const ejs = require('ejs');
const mongoose = require('mongoose'); 
const fileUpload = require('express-fileupload');
//const { resourceUsage } = require('process');

mongoose.connect('mongodb://localhost/my_database', { useNewUrlParser: true }); //Defining a connection

const app = new express();
app.set('view engine', 'ejs');

const validateMiddleware = require('./middleware/validationMiddleware');
const homeController = require('./controllers/home');
const getPostController = require('./controllers/getPost');
const newPostController = require('./controllers/newPost');
const storePostController = require('./controllers/storePost');


app.use(express.static('public'));  
app.use(express.json());
app.use(express.urlencoded());
app.use(fileUpload());
app.use('/posts/store', validateMiddleware);


app.listen(4000, () => {
    console.log('App listening on port 4000');
});


app.get('/', homeController);

app.get('/post/:id', getPostController);

app.get('/posts/new', newPostController);

app.post('/posts/store', storePostController);

3) validationMiddleware.js

module.exports = (req, res, next) => {

    console.log("Executing Validation Middleware")  //Debugging code
    console.log(req.files)                          //Debugging code

    if (req.files == null || req.body.title == "") {

        return res.redirect('/posts/new');
    }
    next();
}

4) storePost.js

const path = require('path');
const BlogPost = require('../models/BlogPost');

module.exports = async (req, res) => {

    let image = req.files.image;

    console.log("Image Name: " + image.name);           //Debugging Code
    console.log("Printing Image : " + req.files.image); //Debugging Code

    image.mv(path.resolve(__dirname, 'public/img', image.name),
        async (error) => {
            await BlogPost.create({
                ...req.body,
                image: '/img/' + image.name
            })
            res.redirect('/');
        });

}
  1. 文件夹结构 Folder structure

也尝试在控制器中使用控制台 req.files 而不是 req.files.image 再次调试后还尝试将验证转换为 function() ,将其导出并在控制器中调用它并使用回调.

错误是,我从控制器文件夹中操作 storePost.js 并且我从 index.js 位于根文件夹中。

path.resolve() 方法需要一个 up 文件夹 & 我们必须在 __dirname[=23 之后传递一个附加参数作为 '..' =]

观察为 path.resolve() 方法提供的参数。以下代码是正确的做法:

image.mv(path.resolve(__dirname, '..', 'public/img', image.name),
        async (error) => {
            await BlogPost.create({
                ...req.body,
                image: '/img/' + image.name
            })
            res.redirect('/');
        });

一个小错误导致一大堆错误,我无法追查。终于解决了错误。