LoginSignup
14
15

More than 3 years have passed since last update.

Node.js(Express) + Multer + S3で画像をフォームからアップロードする

Posted at

目的

フォームから画像やファイルをクラウド上(今回はS3)にアップロードするため

背景

最近Nodeを触っていて、ググっても色々情報はあるものの、フォームからS3に上げるどうこうっていうのはまとまってなかったので。

前提条件

・AWS
・S3
・環境変数、aws-sdk, multer, multer-s3をインストールしておくこと
上記のセットアップが終わっていること。

コード

node.js
var express = require('express');
var router = express.Router();
var path = require('path');
var AWS = require('aws-sdk');
var multer = require('multer');
var multerS3 = require('multer-s3');

const s3 = new AWS.S3({
  accessKeyId: process.env.AWS_S3_ACCESS_KEY_ID, 
  secretAccessKey: process.env.AWS_S3_SECRET_KEY,
  Bucket: '自分のバケット'
});

const profileImgUpload = multer({
  storage: multerS3({
    s3: s3,
    bucket: '自分のバケット',
    metadata: function (req, file, cb) {
      cb(null, {fieldName: file.fieldname});
    },
    key: function (req, file, cb) {
      cb(null, Date.now() + file.originalname);
    }
  }),
  limits: { fileSize: 2000000 }, // In bytes: 2000000 bytes = 2 MB
  fileFilter: function (req, file, cb) {
    checkFileType(file, cb);
  }
}).single('フォーム上のnameのパラメータ');

function checkFileType (file, cb) {
  // Allowed ext
  const filetypes = /jpeg|jpg|png|gif/;
  // Check ext
  const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
  // Check mime
  const mimetype = filetypes.test(file.mimetype);
  if (mimetype && extname) {
    return cb(null, true);
  } else {
    cb('Error: Images Only!');
  }
}

router.get('/', function (req, res, next) {
  var data = {
    title: '画像アップロード',
  };
  res.render('index', data);
});

router.post('/profile-img-upload', (req, res, next) => {
  profileImgUpload(req, res, (error) => {
    if (error) {
      console.log('errors', error);
      res.json({ error: error });
    } else {
      // If File not found
      if (req.file === undefined) {
        console.log('Error: No File Selected!');
        res.json('Error: No File Selected');
      } else {
        // If Success
        const imageName = req.file.key;
        const imageLocation = req.file.location;
        // Save the file name into database into profile model
        res.json({
          image: imageName,
          location: imageLocation
        });
      }
    }
  });
});

index.pug
form(action='/profile-img-upload', enctype='multipart/form-data', method='post') 

h3 プロフィールイメージ
 input(type='file', name='profileImage')
 input(type='submit', value='登録')

感想

バババッと適当に書いてしまったので、もし質問等あれば、コメントください!

何を思ったのか急に投稿してみようって思ったので、初投稿です。
大した記事でないけれど、次回以降は丁寧に書いて、価値のある記事を書きます

14
15
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
15