💩

Express × multer × fsで大量の画像を繰り返し処理で表示する

2022/05/02に公開

multer で保存処理した画像を、繰り返し処理で表示する方法です。
画像アップロード方法の情報は多かったのですが、複数の画像表示に関してはドキュメントを見てやっと実装したので、備忘録です。

こんな感じでビューに画像を表示したいです。

views/images.ejs
<% images.forEach(image => { %>
  <img src=<%= image %> class="card-image-top" alt="">
<% }) %>

ここから、画像データの配列があれば実装できそうです。

結論

  1. multer で画像を指定したディレクトリに保存します。
  2. fs でそのディレクトリのデータを配列にして取り出します。
  3. 取り出した配列を res.render(.. でビューに渡します。
routes/image.js
const express = require('express');
const router = express.Router();

const path = require('path');

// 指定ディレクトリ内のデータを配列で取得するために使用
const fs = require('fs');

// --> multerの設定
const multer  = require('multer')
const storage = multer.diskStorage({
  destination: function(req, file, cb){
      // 画像を保存するディレクトリを指定
    cb(null, './public/images/')
  },
      // 画像データ保存時のファイルネームを変更
  filename: function(req, file, cb){
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9)
    cb(null, file.fieldname + '-' + uniqueSuffix)
  }
})
const upload = multer({ storage: storage })
// <--

// Get images
router.get('/images', (req, res, next) => {
    // 2. fsのメソッドである readdir にて指定ディレクトリ内のデータを配列で取得
  // readdirSync で同期的に処理を行います。
  // readdirの非同期では処理が追いつかずエラーが起きます。
  const images = fs.readdirSync('./public/images/');

  if (images.length >= 0) {
    // 3. 画像データの配列をビューに渡す
    res.render('images.ejs', { images: images });
  }
  else {
    consosle.error('There is something wrong about fs / images!');
  }
})

// Create images
// upload.single('image')はmulterによるものです
// 1. これで指定したディレクトリに画像が保存されます
router.post('/images/upload', upload.single('image'), (req, res, next) => {
  if (req.file) {
    console.log('Image uploaded!');
    res.redirect('/images');
  }
  else {
    console.log('Image can not uploaded!')
    res.render('image.ejs');
  }
})

これで、大量の画像を繰り返し処理によって表示できました。

参考

multer
fs

Discussion