无法从 ejs Web 应用程序的正文中获取数据

问题描述 投票:0回答:1

我正在使用nodejs、ejs 模板、mongodb 和express 创建一个Web 应用程序。我创建了多条路线。对于用户以及其他数据库。我成功地能够从 /register 路由的 post 请求中获取。但无法从 /admin/blog/edit/:id 路由的正文中获取任何内容。浏览器和控制台中的错误为零。但当我获取主体时,我得到空对象。

这是我的 app.js 代码:

if (process.env.NODE_ENV !== 'production') {
    require('dotenv').config()
}



const express = require('express');
const mongoose = require('mongoose');
const ejsLayouts = require('express-ejs-layouts');
const cors = require('cors');
const passport = require('passport');
const flash = require('express-flash');
const session = require('express-session');
const methodOverride = require('method-override');
const webRoutes = require('./routes/webRoutes');
const userRoutes = require('./routes/userRoutes');
const initializePassport = require('./passport-config');

const app = express();

app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static(__dirname + '/public'));

app.set('view engine', 'ejs');
app.use(ejsLayouts);

app.use(function(req, res, next) {
    res.locals.currentPage = req.path;
    next();
});


app.use("/", webRoutes);
app.use("/admin", userRoutes);

mongoose.connect('mongodb://127.0.0.1:27017/farsaa');

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`);
});

这是我的 userRotes.js 代码:

if (process.env.NODE_ENV !== 'production') {
    require('dotenv').config()
}


let express = require('express');
const app = express();
const router = express.Router();
const bcrypt = require('bcrypt');
const passport = require('passport');
const flash = require('express-flash');
const session = require('express-session');
const methodOverride = require('method-override');
const fs = require('fs');
const path = require('path');
// const User = require('../models/userModel');
const { Blog, Contact, JobOpening, User } = require('../models/dbModels');

const initializePassport = require('../passport-config')
initializePassport(
    passport, 
    email => users.find(user => user.email === email),
    id => users.find(user => user.id === id)
)



router.use(flash())
router.use(session({
    secret: process.env.SECRET_KEY,
    resave: false,
    saveUninitialized: false
}))
router.use(passport.initialize())
router.use(passport.session())
router.use(methodOverride('_method'))

// Function to get JavaScript filenames
function getAdminJSFiles() {
    const adminJsDir = path.join(__dirname, '..', 'public', 'javascript', 'admin');
    const files = fs.readdirSync(adminJsDir);
    const jsFiles = files.filter(file => file.endsWith('.js'));
    return jsFiles;
}

// Function to get JavaScript filenames
function getAdminCSSFiles() {
    const adminCSSDir = path.join(__dirname, '..', 'public', 'styles', 'admin');
    const files = fs.readdirSync(adminCSSDir);
    const cssFiles = files.filter(file => file.endsWith('.css'));
    return cssFiles;
}

const current_user = true;


// Middleware to set layout for all admin routes
router.use((req, res, next) => {
    if (req.originalUrl.startsWith('/admin/login')) {
        // Exclude layout for login routes
        res.locals.layout = 'layout_login';
        return next();
    }
    res.locals.layout = 'layout_admin'; // Specify the admin layout
    res.locals.jsFiles = getAdminJSFiles(); // Pass the jsFiles variable
    res.locals.cssFiles = getAdminCSSFiles(); // Pass the jsFiles variable
    res.locals.user = { name: "afzal", email: 'afzal@gmail'}
    next();
});


router.use((req, res, next) => {
    if (req.isAuthenticated()) {
        if (req.originalUrl === '/admin/login') {
            return res.redirect('/admin');
        }
        return next();
    }
    if (req.originalUrl === '/admin/login') {
        return next();
    }
    res.redirect('/admin/login');
});

router.get('/', (req, res) => {
    res.render('./admin/admin_home', { current_user: req.body.email, email: req.body.name, params: req.params });
});

router.get('/register', (req, res) => {
    res.render('./admin/admin_register');
});

router.post('/register', async (req, res) => {
    try {
        const hashedPassword = await bcrypt.hash(req.body.password, 10);
        const newUser = new User({
            email: req.body.email,
            password: hashedPassword,
            role: req.body.role
        });
        await newUser.save();
        res.redirect('/admin/login');
    } catch (error) {
        console.error(error);
        res.redirect('/admin/register');
    }
});

router.get('/login', (req, res) => {
    res.render('./admin/admin_login');
});

router.post('/login', passport.authenticate('local', {
    successRedirect: '/admin',
    failureRedirect: '/admin/login',
    failureFlash: true
}));

router.get('/logout', (req, res, next) => {
    req.logout((err) => {
        if (err) { return next(err); }
        res.redirect('/admin');
    });
});

router.get('/blogs', async (req, res) => {
    try {
      const blogs = await Blog.find();
      res.render('./admin/blogs/blog_home', { blogs });
    } catch (err) {
      console.error(err);
      res.status(500).send('Server Error');
    }
  });


router.get('/blogs/add', async (req, res) => {
    try {
      res.render('./admin/blogs/blog_add', { action: `/admin/blog/add`, blog: {} });
    } catch (err) {
      console.error(err);
      res.status(500).send('Server Error');
    }
}); 

router.get('/blogs/edit/:id', async (req, res) => {
    try {
        const blog = await Blog.findById(req.params.id);
      res.render('./admin/blogs/blog_add', { action: `/admin/blogs/edit/${blog._id}`, blog });
    } catch (err) {
      console.error(err);
      res.status(500).send('Server Error');
    }
});

router.post('/blogs/edit/:id', async (req, res) => {
    try {
        // const { title, seo_name, blog_type, author_name, image, banner_image, publish_date, status, trending, long_description } = req.body;
        // const updatedBlog = {
        //     title,
        //     seo_name,
        //     blog_type,
        //     author_name,
        //     image,
        //     banner_image,
        //     publish_date,
        //     status,
        //     trending,
        //     long_description
        // };
        const userID = req.params.id;
        console.log(userID)
        // await Blog.findByIdAndUpdate(req.params.id, updatedBlog);
        const { title } = req.body;
        console.log('Request Body:', req.body); // Log request body
        console.log('Update Query:', { title }); // Log update query
        // await Blog.findByIdAndUpdate(req.params.id, { title });
        res.redirect('/admin/blogs');

    } catch (err) {
      console.error(err);
      res.status(500).send('Server Error');
    }
});


module.exports = router;

这是我的 blog_add.ejs 代码:

<div class="content-wrapper">
    <section class="content-header">
        <h1>New</h1>
        <div class="breadcrumb">
            <a class="btn btn-sm btn-info" href="/admin/blogs">Back</a>
        </div>
    </section>
    <section class="content">
        <%- include ('../../partials/admin_form')%>
    </section>
</div>

这是我的 admin_form.ejs 代码:

<% // include partials/layouts/include_ckeditor.ejs %>
<div class="box box-default">
    <div class="box-header with-border">
        <h3 class="box-title">Form</h3>
        <div class="box-tools pull-right">
            <button class="btn btn-box-tool" data-widget="collapse">
                <i class="fa fa-minus"></i>
            </button>
        </div>
    </div>
    <% // - var f = locals.f; %>
    <h1><%= blog ? 'Edit blog' : 'Add blog' %></h1>
    <form action="<%= action %>" method="post" enctype="multipart/form-data">
        <div class="box-body">
            <div class="row">
                <div class="col-md-6">
                    <div class="form-group">
                        <label>Title</label>
                        <input type="text" name="title" class="form-control" placeholder="Enter Title" value="<%= blog.title || '' %>">
                    </div>
                    <div class="form-group">
                        <label>SEO Name</label>
                        <input type="text" name="seo_name" class="form-control" placeholder="Enter SEO Name" value="">
                    </div>
                    <div class="form-group">
                        <label>Blog Type</label>
                        <select name="blog_type" class="form-control">
                            <option value="BLOG">BLOG</option>
                            <option value="NEWS">NEWS</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label>Author Name</label>
                        <input type="text" name="author_name" class="form-control" placeholder="Enter Author Name" value="">
                    </div>
                    <div class="form-group">
                        <label>Image</label>
                        <input type="file" name="image" class="form-control">
                        <p style="color:red;">(530px X 429 px)</p>
                    </div>
                    <div class="form-group">
                        <label>Banner Image</label>
                        <input type="file" name="banner_image" class="form-control">
                        <p style="color:red;">(1015px X 452 px)</p>
                    </div>
                    <div class="form-group">
                        <label>Publish Date</label>
                        <input type="text" name="publish_date" class="form-control" placeholder="Enter Publish Date" id="adrt-datepicker" autocomplete="off" value="">
                    </div>
                    <div class="form-group">
                        <label>Status</label>
                        <input type="checkbox" name="status">
                    </div>
                    <div class="form-group">
                        <label>Trending Blog</label>
                        <input type="checkbox" name="trending">
                    </div>
                </div>
                <div class="col-md-6">
                    <div class="form-group">
                        <label>Long Description</label>
                        <textarea name="long_description" class="form-control"></textarea>
                    </div>
                </div>
            </div>
        </div>
        <div class="box-footer">
            <button type="submit" class="btn btn-primary">Submit</button>
        </div>
    </form>
</div>

<script>
    $(document).ready(function(){
        $("#adrt-datepicker").datepicker({
            dateFormat: 'dd/mm/yy',
            maxDate: 0
        });
    });
</script>

问题是,当我尝试在 /admin/blogs/edit/:id 路径中提交表单时,没有从表单中获取任何数据。 id 已正确获取,但未从正文中获取数据。这是 body req 的 console.log 输出:

id: 65eb8dce672a051114e1a090
Request Body: {}
Update Query: { title: undefined }
node.js mongodb forms express ejs
1个回答
0
投票

问题出在模板中的表单元素:

“方法=“帖子”enctype=“multipart/form-data”>

属性

enctype="multipart/form-data"
将表单作为多部分表单数据类型发送,这是上传文件时使用的常用类型,但是服务器上没有可以处理该格式的中间件(常用工具是multer),这这就是为什么
req.body
未定义。

如果您从表单中删除该属性,表单将以 URL 编码类型发送,并且

express.urlencoded
中间件将处理它,您将得到
req.body

但是,由于您的表单中有两个文件类型字段,

image
banner_image
,因此您需要发送多部分类型请求,并且在服务器上,您需要设置多部分中间件,以及文件上传、目的地、命名等

因此,如果您不上传文件,只需删除

enctype="multipart/form-data"
属性即可:

<form action="<%= action %>" method="post" enctype="multipart/form-data">

但是如果你要在服务器上上传文件,你需要设置上传中间件,例如,你可以使用

multer
,这就是你的代码的样子(你需要确定你要如何做处理文件、保存文件的位置、命名等,请参阅链接的文档和示例,它们也在这里使用):

// setup upload middleware
const multer  = require('multer');
// setup file destination - you could use in-memory also
const upload = multer({ dest: 'uploads/' });

// you send two file fields, so need to use .fields() method:
const cpUpload = upload.fields([{ name: 'image', maxCount: 1 }, { name: 'banner_image', maxCount: 1 }]);

// add midleware to the route
router.post('/blogs/edit/:id', cpUpload, async (req, res) => {

// handle files, they're in `req.files`
console.log('files', req.files);
© www.soinside.com 2019 - 2024. All rights reserved.