通过表单从不同字段上传多个文件并使用express multer存储到mongodb数据库中

Posted

技术标签:

【中文标题】通过表单从不同字段上传多个文件并使用express multer存储到mongodb数据库中【英文标题】:Uploading multiple files through form from different fields and storing into mongodb databse using express multer 【发布时间】:2020-09-06 19:46:25 【问题描述】:

我正在尝试使用 multer 将两个图像文件上传到一个名为 cast 的数据库中。我将图像作为表单的输入。我意识到有时它会从所有输入字段中获取文件,但有时它只接受一个图像文件作为输入。 有人可以帮我吗?提前谢谢你

adminUpload.ejs

<html>
    <body>
        <form class="uploadForm" method="post" action="/admin/postFile" enctype="multipart/form-data">
            <label>Enter the name of the actor</label><br>
            <input type="text" name="actor"><br>
            <label class="control-label">Upload the image of the actor</label><br>
            <input name="uplactor" type="file" class="file"><br>
            <label>Enter the name of the actress</label><br>
            <input type="text" name="actress"><br>
            <label class="control-label">Upload the image of the actress</label><br>
            <input name="uplactress" type="file" class="file"><br>
            <input type="submit" value="submit" />
        </form>
    </body>
</html>

AdminRouter.js

const express = require('express')
const router = express.Router()
const controller=require('../Controller/Admin');
const multerFileUpload=require("../Models/Admin")
router.get('/postFile',(req,res)=>
    res.render('adminUpload.ejs');
    )
var tempupload=multerFileUpload.upload.fields([
    name: 'uplactor',maxCount: 1,
    name: 'uplactress',maxCount: 1])
router.post("/postFile",tempupload,controller.uploadDB)

module.exports=router;

Admin.js

const multer = require('multer');
const storage= multer.diskStorage(
    destination: (req, file, cb) => 
        if (file.fieldname === 'uplactor'||file.fieldname === 'uplactress'||file.fieldname === 'director'||file.fieldname === 'uplSideCharacter') 
            // if uploading cast photo
            cb(null, 'public/cast_images')
          
        else if(file.fieldname === 'uplTrailer')
            // else uploading trailer 
            cb(null, 'public/trailers')
          
        else if(file.fieldname === 'uplMovie')
            // else uploading movie
            cb(null, 'public/movies')
        
        else if(file.fieldname === 'uplposter')
            // else uploading poster
            cb(null, 'public/posters')
          
        cb(null, 'public/posters');
    ,
    filename: (req, file, cb) => 
        cb(null, file.originalname)
    
);

const fileFilter = (req, file, cb) => 
    if(file.fieldname === 'uplactor'||file.fieldname === 'uplactress'||file.fieldname === 'director'||file.fieldname === 'uplSideCharacter'||file.fieldname === 'uplposter')
    if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)) 
        return cb(new Error('You can upload only image files!'));
    
    else
    cb(null, true);
    
    
    if(file.fieldname === 'uplMovie'||file.fieldname === 'uplTrailer')
    if (!file.originalname.match(/\.(mp4|mp3)$/)) 
        return cb(new Error('You can upload only video files!'));
    
    else
    cb(null, true);
    
    
;
exports.upload = multer( storage:storage, fileFilter: fileFilter );

Admin.js(控制器文件)

const Cast = require('../Models/Cast');
exports.uploadDB=async (req,res)=>
    try
        console.log(req.files)
        console.log(req.files.uplactor[0])
        console.log(req.files.uplactress[0])
    const actor=new Cast(
        name:req.body.actor,
        image:req.files.uplactor[0].filename
    )
    const actress=new Cast(
        name:req.body.actress,
        image:req.files.uplactress[0].filename
    )
    await actor.save();
    await actress.save();
    res.statusCode = 200;
    res.setHeader('Content-Type', 'application/json');
    res.send("hello");
     catch(err)
      res.send(err);
     

app.js

'use strict';
const express = require('express');
const http = require('http');
const morgan = require('morgan');
const bodyParser = require('body-parser');
const AdminRouter = require('./Routes/AdminRoutes');
const mongoose = require('mongoose');
const app=express()
const server = http.createServer(app);
server.listen(3000, 'localhost', () => 
  console.log('server running');
);
app.use(morgan('dev'));
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.urlencoded( extended: true ));
app.use(bodyParser.json());
app.set('views', 'views');
app.set('view engine', 'ejs');
app.use('/admin',AdminRouter);
//connection to mongodb
const url = 'mongodb://localhost:27017/Movie';
const connect = mongoose.connect(url, useNewUrlParser : true, useUnifiedTopology: true   );
connect.then(() => 
  console.log("Connected correctly to server");
, (err) =>  console.log(err); );

Cast.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const CastSchema = new Schema(
    name: 
        type: String,
        required: true,
        unique: true
    ,
    image: 
        type: String,
        required: true
    
)
const Cast = mongoose.model('Cast', CastSchema)
module.exports= Cast

【问题讨论】:

I realized that some times it takes files from all the input fields but sometimes it accepts only one image file as input 表示是否有任何错误或 req.files 不包含正确的文件或什么? @DimplePatel 感谢您的回复。这意味着当我在 Admin.js(控制器文件)中的 console.log(req.files) 有时它会显示两个文件,因为我在 adminUpload.ejs 中将两个文件作为输入,但有时它只显示一个文件 你检查过浏览器检查器发送的http请求,看看这两个文件是否真的发送了吗? 顺便说一下,您应该将图像存储为Buffer 格式而不是String 【参考方案1】:

我已经获取了您的代码并对其进行了调试。最后,我使用了 4 个图像(其中 2 个的大小为 KB,2 个为 9-10 MB)用于测试目的,发现当一个或两个输入时存在问题大尺寸(MB)的文件。 因此,在 uploadDB 方法中,您创建了两个 Cast 模型实例,然后将其保存。为了解决您的问题,创建一个实例保存它,然后创建第二个实例并保存它。

const actor = new Cast(
            name: req.body.actor,
            image: req.files.uplactor[0].filename
        );
        await actor.save();
        console.log(req.files.uplactress[0]);

        const actress = new Cast(
            name: req.body.actress,
            image: req.files.uplactress[0].filename
        );
        await actress.save();

希望这可能会有所帮助

Output:

【讨论】:

嘿,谢谢你的回复。我按照你的建议编辑了代码后在问题中添加了一张图片。我仍然有同样的问题。你可以看到 uplactress 没有任何文件 req.files.uplactress 包含其他字段,一旦await actor .save() 的执行将完成,所以在await actor .save() 之后移动console.log(req.files.uplactress[0])。即使根据您的图像 uplactress 没有任何文件,但请检查您的图像将存储它的文件夹包含您上传的图像并检查到数据库以及它已更新记录 我已在我的答案中附加了控制台输出。请检查您的数据库和输出文件夹,让我知道它是否有效

以上是关于通过表单从不同字段上传多个文件并使用express multer存储到mongodb数据库中的主要内容,如果未能解决你的问题,请参考以下文章

如何从不同的上传点在同一页面上上传多个文件。使用 nodejs express-fileupload

为啥 formData 不适用于多个文件?

使用 dropzone 和使用 FormValidation 插件的其他表单字段上传多个文件

从不同文件夹上传 HTML 多个文件

通过表单上传文件后如何清除输入字段

Jasny 与其他表单元素一起上传多个文件