简体   繁体   English

显示使用 Multer 上传的图像

[英]Display image uploaded using Multer

I'm using Multer to upload images to my server, and I'm using mongo to store them, but I can't get them to be displayed... I'm building a sort of Movies collection.我正在使用 Multer 将图像上传到我的服务器,并且我正在使用 mongo 来存储它们,但我无法让它们显示出来......我正在构建一种电影集合。 The image gets uploaded to mongoDB but I can't manage to render it.图像被上传到 mongoDB 但我无法渲染它。 See code查看代码

index.js index.js

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', (req, res) => {
  res.redirect('/collection');
});

module.exports = router;

collection.js集合.js

var express = require('express');
var router = express.Router();
const multer = require('multer');

const movie_controller = require('../controllers/movieController');

const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, 'public');
  },
  filename: (req, file, cb) => {
    const suffix = file.mimetype.split('/');
    cb(null, `${file.fieldname}-${Date.now()}.${suffix[1]}`);
  },
});

const upload = multer({ storage });

router.get('/', movie_controller.index);

router.get('/movie/create', movie_controller.movie_create_get);

router.post(
  '/movie/create',
  upload.single('image'),
  movie_controller.movie_create_post
);

router.get('/movie/:id/delete', movie_controller.movie_delete_get);

router.post('/movie/:id/delete', movie_controller.movie_delete_post);

router.get('/movie/:id/update', movie_controller.movie_update_get);

router.post(
  '/movie/:id/update',
  upload.single('image'),
  movie_controller.movie_update_post
);

router.get('/movie/:id', movie_controller.movie_detail);

router.get('/movies', movie_controller.movie_list);

movie_controller.js电影控制器.js

const Movie = require('../models/movie');
const { body, validationResult } = require('express-validator');

var async = require('async');

// ...

exports.movie_create_post = [
  (req, res, next) => {
    if (!(req.body.genre instanceof Array)) {
      if (typeof req.body.genre === 'undefined') req.body.genre = [];
      else req.body.genre = new Array(req.body.genre);
    }
    next();
  },
  body('title', "Title can't be empty").trim().isLength({ min: 1 }).escape(),
  body('year', "Year can't be empty").trim().isLength({ min: 1 }).escape(),
  body('duration').trim().optional({ checkFalsy: true }).escape(),
  body('synopsis', "Summary can't be empty").trim().isLength({ trim: 1 }).escape(),
  body('director', "Director can't be empty").trim().isLength({ min: 1 }).escape(),
  body('imdb').trim().optional({ checkFalsy: true }).escape(),
  body('genre.*').escape(),

  (req, res, next) => {
    const errors = validationResult(req);

    let movie = new Movie({
      title: req.body.title,
      year: req.body.year,
      duration: req.body.duration,
      synopsis: req.body.synopsis,
      director: req.body.director,
      imdb: req.body.imdb,
      genre: req.body.genre,
      image: req.file.path,
    });

    console.log(req.body, req.file);

    if (!errors.isEmpty()) {
      async.parallel(
        {
          directors: (callback) => {
            Director.find(callback);
          },
          genres: (callback) => {
            Genre.find(callback);
          },
        },
        (err, results) => {
          if (err) {
            return next(err);
          }

          for (let i = 0; i < results.genres.length; i++) {
            if (movie.genre.indexOf(results.genres[i]._id) > -1) {
              results.genres[i].checked = 'true';
            }
          }
          res.render('movie_form', {
            title: 'New Movie',
            directors: results.directors,
            genres: results.genres,
            movie: movie,
            errors: errors.array(),
          });
        }
      );
      return;
    } else {
      movie.save((err) => {
        if (err) { return next(err); }
        res.redirect(movie.url);
      });
    }
  },
];

// ...

exports.movie_update_post = [
  (req, res, next) => {
    if (!(req.body.genre instanceof Array)) {
      if (typeof req.body.genre === 'undefined') req.body.genre = [];
      else req.body.genre = new Array(req.body.genre);
    }
    next();
  },
  body('title', "Title can't be empty").isLength({ min: 1 }).escape(),
  body('year', "Year can't be empty").isLength({ min: 1 }).escape(),
  body('duration').optional({ checkFalsy: true }).escape(),
  body('synopsis', "Summary can't be empty").isLength({ trim: 1 }).escape(),
  body('director', "Director can't be empty").isLength({ min: 1 }).escape(),
  body('imdb').optional({ checkFalsy: true }).escape(),
  body('genre.*').escape(),

  (req, res, next) => {
    const errors = validationResult(req);

    let movie = new Movie({
      title: req.body.title,
      year: req.body.year,
      duration: req.body.duration,
      synopsis: req.body.synopsis,
      director: req.body.director,
      imdb: req.body.imdb,
      genre: typeof req.body.genre === 'undefined' ? [] : req.body.genre,
      _id: req.params.id,
    });

    if (req.file) {
      movie.image = req.file.path;
    }

    if (!errors.isEmpty()) {
      async.parallel(
        {
          directors: (callback) => {
            Director.find(callback);
          },
          genres: (callback) => {
            Genre.find(callback);
          },
        },
        (err, results) => {
          if (err) {
            return next(err);
          }

          for (let i = 0; i < results.genres.length; i++) {
            if (movie.genre.indexOf(results.genres[i]._id) > -1) {
              results.genres[i].checked = 'true';
            }
          }

          res.render('movie_form', {
            title: `Update ${results.movie.title}`,
            directors: results.directors,
            genres: results.genres,
            movie: movie,
            errors: errors.array(),
          });
        }
      );
      return;
    } else {
      Movie.findByIdAndUpdate(req.params.id, movie, {}, (err, themovie) => {
        if (err) {
          return next(err);
        }
        res.redirect(themovie.url);
      });
    }
  },
];

movie.js Schema movie.js架构

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

var MovieSchema = new Schema({
  title: { type: String, required: true },
  year: { type: String, required: true },
  duration: String,
  synopsis: { type: String, required: true },
  director: { type: Schema.Types.ObjectId, ref: 'Director', required: true },
  imdb: String,
  genre: [{ type: Schema.Types.ObjectId, ref: 'Genre', required: true }],
  image: String,
});

MovieSchema.virtual('url').get(function () {
  return '/collection/movie/' + this._id;
});

module.exports = mongoose.model('Movie', MovieSchema);

The image gets uploaded to MongoDB but doesn't get displayed.图像被上传到 MongoDB 但没有显示。 That's how I'm specifying its path这就是我指定其路径的方式

movie_detail.pug movie_detail.pug

div(class='movie-img')
        figure
          img(src=movie.image alt=movie.title)

and here's a screenshot of what I get这是我得到的截图它不会在电影细节上呈现

it doesn't render on movies detail它不会在电影细节上呈现

检查以在新选项卡中打开

Inspecting to open in a new tab检查以在新选项卡中打开

找不到图片

It doesn't find the image找不到图片

I believe the path it's correct.我相信这条路是正确的。 In app.js I already haveapp.js我已经有了

app.use(express.static(path.join(_dirname, 'public')));

Can someone please help me see what I'm doing wrong?有人可以帮我看看我做错了什么吗? I appreciate it.我很感激。

If I understand correctly, you store the image in public folder and save the path in MongoDB with movie.image = req.file.path;如果我理解正确,您将图像存储在public中并将路径保存在 MongoDB 中, movie.image = req.file.path; . . Because you serve static files in public folder, the image should be available at http://localhost:9999/image-1621785191213.jpeg .因为您在public文件夹中提供 static 文件,所以图像应该在http://localhost:9999/image-1621785191213.jpeg The img tag should become: img 标签应该变成:

<img src="/image-1621785191213.jpeg">

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM