📑

【Vue.js × node(Nest.js)】AWS S3に画像をアップロードしてみた①

2023/01/01に公開

はじめに/概要

Vue(フロントエンド)とnode(Nest(バックエンド))を使って、AWSのS3に画像をアップロードする方法を紹介します。

フロントエンドとバックエンドを組み合わせてS3に画像をアップロードする記事があまり見つからなかったので参考になれば嬉しいです。

今回の記事では、フロントエンド側の処理(APIを叩いて、画像をバックエンド側に渡すまで)を紹介します。

対象

S3に画像をアップロードしてみたい方/方法がわからない方

目標

Vue.jsとNest.jsを使って、AWS S3に画像をアップロードできる。

事前準備

Vue.jsとNest.jsの環境構築ができているとします。
AWSアクセスキーの発行ができている状態だとします。

【フロント側】Vue.jsの実装

フロント側からバックエンド側に画像のデータを渡す処理を実装していきます。

Vue.jsファイル

vue.js
<template>
  <div class="editForm">
    <form class="createForm" @submit.prevent="handleSubmit()">
        <div class="bonusImage bonusInfo">
          <h3>画像</h3>
          <label>
            <input
              type="file"
              name=""
              accept=".png, .jpg, .jpeg"
              @change="handleImageUploaded" //画像をアップロードすると発火する関数
            />画像追加
          </label>
	  <img
            v-if="state.imagePath"
            src="state.imagePath"
	  />
        </div>
        <button type="submit">画像を保存</button>
    </form>
  </div>
</template>

<script setup lang="ts">
import { reactive, computed, ref } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import axios from 'axios'
interface State {
  inputFileImg: File,
  imagePath: string,
}
const router = useRouter()
const route = useRoute()
const state: State = reactive({
  inputFileImg: new File(['sample'], '', {
    type: 'image/jpeg',
  }),
  imagePath: '',
})

// APIを叩いてバックエンド側に画像データを送る
const registerImageToS3 = async (image: File) => {
  const formData = new FormData()
  formData.append('file', image) // formDataにappendする必要あり
  const result = await axios
    .post(`${import.meta.env.VITE_API_ORIGIN}/s3/upload`, formData, {
      headers: {
        Authorization: `Bearer ${userStore.token}`,
        'content-type': 'multipart/form-data', // content-typeは'multipart/form-data'である必要あり
      },
    })
    .then((response) => {
      console.log('response', response)
      return response
    })
    .catch((e) => {
      console.log(e)
      throw new e()
    })
  return result
}

// ①画像をuploadすると、画像データがstateに入る
const handleImageUploaded = (e: Event) => {
  if (e.target instanceof HTMLInputElement && e.target.files) {
    state.inputFileBonusImg = e.target.files[0]
  }
}
// ②画像を保存ボタンを押して、発火する関数
const handleSubmit = async () => {
  if (state.inputFileImg.name !== '') {
    const resS3Data = await registerImageToS3(state.inputFileImg)
    state.imagePath = resS3Data.data.Location // s3で発行されたURLをstateに入れる。
  }
}
</script>

最後に

vue.jsから直接s3にアップする方法はいくつかありますが、vue.jsからバックエンド側に渡してs3にアップする方法が見当たらなかったので参考になれば嬉しいです!

以上で終了です。お疲れ様でした!
参考になった方は、ぜひ、いいねをいただけると嬉しいです!

Discussion