【发布时间】:2022-01-03 07:47:37
【问题描述】:
我通过分离模型、视图和控制将我的旧 Demo 项目转换为 MVC 样式,添加了一个新的控制器文件夹。除了存储图像外,所有功能都运行良好。我收到一个错误:Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
我做了一些调试,发现图像在验证过程中存在,但在发送到请求处理程序时不存在 以存储 db 对象。 Please check this image of debugging output
数据库中还有一个奇怪的错误。 标题、正文和图像路径在 DB 中插入了两次。我删除了旧的东西并一次又一次地尝试。但仍然注意到,对于使用 '/posts/new' 页面的一次插入:两个相同的对象被存储在 mongodb 中。 Image attached from Mongo DB compass
这是项目流程:带有图像的请求对象是从“/posts/new”页面中挑选出来的,在验证中间件中进行验证,如果存在标题和图像:它将被发送到请求处理程序app.post('/posts/store', storePostController);它将使用路径存储图像,它将存储一个 mongo db 文档,其中包含数据库中的标题、正文和图像路径。
以下代码如下: 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('/');
});
}
- 文件夹结构 Folder structure
【问题讨论】:
标签: node.js mongodb express model-view-controller file-upload