LoginSignup
19
15

More than 3 years have passed since last update.

Vue.jsとExpressを使って画像アップロードをしてみる

Last updated at Posted at 2019-06-25

はじめまして、PMをやっているtatsukenと申します。はじめまして
研修の一環でvue.js、expressを書くことがあったので、そのことを中心にまとめていきたいと思います

はじめに

Vue.jsからリクエストを投げてExpressのpublicディレクトリに画像をアップロードしてみたいとおもいます。
今回画像アップロードにはmulterというライブラリを使って行きます。

実装

使用するライブラリのインストール

  • axios
    • npm install axios -s Vueプロジェクトの中でinstallしてください
  • multer
    • npm install multer -s Expressプロジェクトの中でinstallしてください

Vueの実装

まず一つvueファイルを作ってください

Uplord.vue
<template>
  <div>
    <form>
      <input type="file" id="file" v-on:change="onFileChange">
      <input type="submit" value="decide" @click="submitClick">
    </form>
  </div>
</template>
<script>
import Axios from "axios";
export default {
    data() {
        return {
            imageFile: null
        };
    },
    methods: {
        //画像が選択されたとき呼ばれる
        onFileChange(e) {
            this.imageFile = e.target.files || e.dataTransfer.files;
        },
        //submitされたときに呼ばれる
        async submitClick() {
            try {
                const formData = new FormData();
                formData.append("file", this.imageFile[0]);
                const config = {
                    headers: {
                        "content-type": "multipart/form-data",
                    }
                };
                let res = await Axios.post("/image", formData, config);
                console.log(res);
                if (res.data.status === "error") {
                    alert(res.data.error);
                } else {
                    alert("登録完了")
                }
            } catch (error) {
                alert("画像の送信に失敗しました");
            }
        }
    }
}
</script>
  • ここではformDataを使って画像をpostしています。
  • formData.append("key",value)を使うことでkey:valueを対応させる形で任意のデータを乗せることが出来ます。

注意点

  • valueにはオブジェクトなどは乗せることが出来ません。基本的にkeyとvalueを一つずつ載せてください。
  • formDataに載せたvalueはStingになってしまいます。

Expressの実装

src/index.jsに以下を書いていきましょう

index.js
const express = require('express')
const multer = require('multer');
const app = express()
const storage = multer.diskStorage({
    // ファイルの保存先を指定(今回はsrc/public/image以下に画像を保存)
    destination: function (req, file, cb) {
        cb(null, 'src/public/image')
    },
    // ファイル名を指定(オリジナルのファイル名を指定)
    filename: function (req, file, cb) {
        // Math.random().toString(36).slice(-9)で乱数を生成
        const imageName = `${Math.random().toString(36).slice(-9)}_${Date.now()}.png`
        cb(null, imageName)
    }
})

const upload = multer({
    storage: storage
}).single('file')

app.post('/image', (req, res) => {
    upload(req, res, (err) => {
        if (err) {
            //アップロード失敗した場合
            res.json({
                status: "error",
                error: "fail to uplord image"
            })
        } else {
            //アップロード成功した場合
            res.json({
                status: "sucess",
                // ファイル名を返す
                path: res.req.file.filename
            })
        }
    })
});
  • const storageで画像の保存先をファイル名を指定
  • ここではファイル名を乱数と時間を組み合わせていますがこれではユニークとは言えません。ユニークにしたい方はuserIdと時間を組み合わせるなどしてください。
  • /imageのエンドポイントでuplordを呼び出しています。ただアップロードするだけでしたらもっと簡単に出来ます。(詳しくはこちら)しかしここではアップロード出来たかどうかのエラーハンドリングを行いたいのでこのような形になっています。
  • アップロードされた画像のファイル名はres.req.file.filenameで取得する事ができます。
  • 無事フロントでres.data.statussucsessになっていれば登録完了です。

最後に

multeraxiosでお手軽にVueからExpressに画像をアップロードすることが出来ました。
機会があれば是非試してみてください
なにか間違いなどありましたら教えていただけると幸いです。

19
15
0

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
19
15