Laravel+Vueにて画像をアップロードする

  • CREATE:2022-07-02
  • UPDATE:2022-07-02

サムネイル:Pixabayより

概要

今回は、以前githubに上げたソースコードをブログに再掲載したものです。

今回のソースコードでできること

  • Laravelにて画面遷移無しで画像をアップロードできるようになる。
  • SPA(シングルページアプリケーション)などでも活用可能


注意

  • 最低限の機能しか実装していません。
  • 一部のファイルしかないので、使用する場合は保存ではなくコピペを用いてください。
  • バリデーション等は一切していません。
  • バリデーション等を実装せずにこのまま使うと、悪意のあるユーザーから、危険なファイルをアップロードされてしまいます。


事前に

以下のコードをコマンドプロンプト等に入力してください。

php artisan storage:link


ソースコード

Welcome.blade.php

<!DOCTYPE html>
	<html lang="ja">
	
	<head>
	    <meta charset="utf-8">
	    <meta name="csrf-token" content="{{ csrf_token() }}">
	    <meta name="viewport" content="width=device-width, initial-scale=1">
	    <title>画像アップローダー</title>
	</head>

	<body>
	    <div id="app">
	        <input v-if="uploader" type="file" accept="image/*" ref="input" @change="uploadimage()" />
	        <!-- アップロードした画像を表示 -->
	        <img v-if="image" :src="image" class="preview" />
	        <!-- アップロードした画像をaxiosからLaravelに渡し、保存する。-->
	        <input type="button" value="投稿する" @click="post">
	    </div>
	    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
	    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
	    <!-- /publicフォルダにjsフォルダを作り格納。 -->
	    <script src="{{ asset('/js/javascript1.js') }}"></script>
	</body>

	</html>


/public/js/javascript1.js

var app = new Vue({
	    el: '#app',
	    data: {
	        uploader:true,
	        data:"",
	        image:""
	    },
	    methods: {
	        uploadimage() {
	            //アップロード用の画像データ
	            this.data  = this.$refs.input.files[0];
	            //表示用の画像
	            this.image = URL.createObjectURL(this.data);
	        },
	

	        //axiosによるアップロード
	        post() {
	            let formData = new FormData();
	            formData.append("data", this.data);

                //これがないと画像のアップロードができない
	            let config = {
	                headers: {
	                    "content-type": "multipart/form-data"
	                }
	            };

        //api.phpにアクセスする場合、先頭に「api」を付ける。
	            axios
	                .post("/api/upload", formData, config)
	                .then(res => {
	                    alert("投稿に成功しました!");
	                    //投稿に成功したらリセット
	                    this.image = "";
	                    this.data = "";
	                    this.reset();
	                })
	                .catch(function() {
	                    alert("投稿に失敗しました。");
	                });
	        },
	
	        reset () {
	            //フォームに格納されたファイルを削除する。
	            //v-ifは、falseになると「削除された扱い」になるらしい。
	            this.uploader = false
	            this.$nextTick(function () {
	                this.uploader = true
	            })
	        }
	    },
	})


<?php
	

	use Illuminate\Http\Request;
	use Illuminate\Support\Facades\Route;
	

	/*
	|--------------------------------------------------------------------------
	| API Routes
	|--------------------------------------------------------------------------
	|
	| Here is where you can register API routes for your application. These
	| routes are loaded by the RouteServiceProvider within a group which
	| is assigned the "api" middleware group. Enjoy building your API!
	|
	*/
	

	Route::post('/upload', '\App\Http\Controllers\ImageController@upload');


<?php
	

	namespace App\Http\Controllers;
	

	use Illuminate\Http\Request;
	

	class ImageController extends Controller
	{
	    function upload(Request $request)
	    {
	        //ファイル名取得
	        $filename = $request->data->getClientOriginalName();

	        //ファイル名を変更せずにアップロード
	        $imagedata = $request->file('data')->storeAs('public/images', $filename);
	    }
	}


あとがき

この方法は、少し改造すれば、Laravel+Nuxt.jsでも可能と思います。