1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

laravel + vue.jsのファイルアップロードについて

Last updated at Posted at 2021-01-03

###この記事を書いたきっかけ
これから始めるvue.js実践入門(山田祥寛)のファイルアップロードの項目を見ていて、laravel+vueの時には同じ書き方だと動かないことに気づいたから。

###vue.jsでは普通はどうするの?

test.vue
new Vue({
  el: '#app',
  data: {
    message: ''
  },
  methods: {
    onchange: function() {
      let that = this;
      let fl = this.$refs.upfile.files[0];
      let data = new FormData();
      data.append('upfile', fl, fl.name);
      fetch('upload.php', { 
        method: 'POST',
        body: data,
      }) 
      .then(function (response) {
        return response.text();
      })
      .then(function (text) {
        that.message = text;
      })
      .catch(function (error) { 
        window.alert('Error: ' + error.message);
      });
    }
  }
});

(upload.phpは省略します。下にあるtest.blade.phpと内容は同じです。)

####試したこと1
resources/js/app.jsと、resources/js/components/Mycomponents.vueに上記のファイルの内容を配置しupload.phpをcomponents配下にupload.phpを置いてみる(雑。)
結果:
fileupload後に、「No input file specified. file upload」のメッセージが返ってくる。(失敗)

####寄り道はこれくらいにして・・・・・・

myComponent.vue
    <form>
       <input ref="upfile" type="file" v-on:change="onchange3" />
       <input type="hidden" name="_token" v-bind:value="csrf">
    </form>
    <br />
    <p>{{ message }}</p>
    <br />

<script>
  data: function () {
    return {
      csrf: document.head.querySelector('meta[name="csrf-token"]').content,
    };
  },
  methods: {
 onchange3: function() {
      let that = this;
      let fl = this.$refs.upfile.files[0];
      let data = new FormData();
      data.append('upfile', fl, fl.name);

      fetch('/hello/fileupload',{
        method: 'POST',
        body: data,
        headers: {"X-Requested-With": "XMLHttpRequest",
        'X-CSRF-TOKEN':this.csrf}
      })
      .then(function(response){
        return response.text();
      })
      .then(function(text){
        that.message = text;
      })
      .catch(function(error){
        window.alert('Error:' + error.message3);
      });
    }
}
</script>
web.php
Route::post('/hello/fileupload', [HelloController::class, 'file']);
HelloController.php
class HelloController extends Controller
{
    public function file()
    {
        return view('hello.test');
    }
}
test.blade.php
<?php
$error = false;
if ($_FILES['upfile']['error'] !== UPLOAD_ERR_OK) { 
  $error = true;
} else {
  $src = $_FILES['upfile']['tmp_name']; 
  $dest = mb_convert_encoding($_FILES['upfile']['name'], 'SJIS-WIN', 'UTF-8');
  if (!move_uploaded_file($src, $dest)) { $error = true; }
}
if ($error) {
  header('HTTP/1.1 500 Internal Server Error');
  print 'アップロードできませんでした。';
} else {
  print 'アップロード成功:'.$dest;
}
?>
index.blade.php
<!doctype html>
<html lang="ja">
<head>
    <title>Index</title>
    <link href="{{ mix('css/app.css') }}"  rel="stylesheet" type="text/css">
    <meta name="csrf-token" content="{{ csrf_token() }}">
</head>
<body>
<-- 以下省略 -->

これでとりあえずは(?)うまくいっているように見えました。
・非同期処理でaxiosをつかっていないところ
・laravelのファイルアップロード機能をつかっていないところ

等、通常のやり方でないところもあると思うのですが、一応一つのやり方のメモとして参考になればと存じます。ここまで読んでいただきありがとうございました。

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?