使用 vuejs 和 laravel 上传文件,无需表单

Posted

技术标签:

【中文标题】使用 vuejs 和 laravel 上传文件,无需表单【英文标题】:Upload a file using vuejs and laravel without a form 【发布时间】:2018-01-14 22:21:35 【问题描述】:

我正在使用 vue.js 2.1 和 Laravel 5.4 从没有表单的组件上传文件。

问题:在服务器端,这条语句return $request->file('my_file'); 返回null。为什么?

vue 组件是这样的:

<template>
    <input id="my_file" type="file" @change="fileChanged($event)">
    <button v-if="my_file" @click="update">Upload</button>
</template>

<script>
export default 
    data () 
        return 
            my_file: null,
        
    ,

    methods: 
        fileChanged(e) 
            var files = e.target.files || e.dataTransfer.files;
            if (!files.length)
                return;
            this.createImage(files[0]);
        ,

        createImage(file) 
            var image = new Image();
            var reader = new FileReader();
            var vm = this;

            reader.onload = (e) => 
                vm.my_file = e.target.result;
            ;
            reader.readAsDataURL(file);
        ,

        update() 
            axios.put('/api/update/', 
                my_file: this.my_file,
            )
            .then(response => 
                console.log(response.data);
            )
            .catch(error => 
                console.log(error);
            );
        
    

</script>

在服务器端,我有以下方法:

public function update(Request $request)

    return $request->file('my_file');

    // $request->file('my_file')->store();

我错过了什么?所以我可以使用 Laravel 提供的函数$request-&gt;file('my_file')-&gt;store(); 来上传文件。

编辑 我已将 http 动词从 put 更改为 post,如下所示:

trySomeThing () 
    var data = new FormData();
    var file = this.$refs.fileInput.files[0];
    data.append('attachment_file', file);
    data.append('msg', 'hello');

    axios.post('/api/try', data)
        .then(response => 
            console.log(response.data)
        );
,

在控制器上,我有:

public function try(Request $request)

    if ($request->hasFile('my_file')) 
        $file = $request->file('my_file');
        //$file->getFilename();
        return var_dump($file);
     else 
        return var_dump($_POST);
    

请求头包含:

返回的响应显示如下:

【问题讨论】:

在 vuejs 中使用 formData medium.com/@jagadeshanh/… 【参考方案1】:

首先在你的文件输入中添加一个 Vue 引用。

<input id="my_file" type="file" @change="fileChanged($event)" ref="fileInput">

然后更新您的update 方法:

update() 
    var data = new FormData()
    var file = this.$refs.fileInput.files[0]
    data.append('my_file', file)
    axios.put('/api/update/', data)     
    .then(response => 
        console.log(response.data)
    )
    .catch(error => 
        console.log(error)
    );

在您的 laravel 应用程序中:

if ($request->hasFile('my_file')) 
   $file = $request->file('my_file');
   dd($file);

欲了解更多信息:Laravel documentation

【讨论】:

如何从服务器端检索数据?我试图 return $request-&gt;my_file; 但返回 null。在 chrome devTools 上,我看到发送的请求包含:------WebKitFormBoundary9lOFAy36UFyjOmoh Content-Disposition: form-data; name="attachment_file"; filename="794a4be39f0b96b4d5787e3e31f8b622.jpg" Content-Type: image/jpeg ------WebKitFormBoundary9lOFAy36UFyjOmoh 我在你的 php 测试中添加了一个 else。它返回 else 块中的内容。这意味着$request-&gt;hasFile('my_file') 返回了false 请查看我的问题编辑。我什至尝试过发布。 php 没有得到它。 @Warrio 你能试着检查一下$request-&gt;hasFile('attachement_file') 吗? @Ikbel:FormData 不适用于动词 PUT :\ 但适用于 POST!!【参考方案2】:

你的视图应该是这样的

<template>
<div class="row">
    <div class="col-md-12">
        <div class="col-md-2">
            <img :src="image" class="img-responsive">
        </div>
        <div class="col-md-8">
            <input type="file" v-on:change="onFileChange" class="form-control">
        </div>
        <div class="col-md-2">
            <button class="btn btn-success btn-block" @click="upload">Upload</button>
        </div>
       </div>
   </div>
</template>
<style scoped>
img
    max-height: 36px;

</style>
<script>
    export default
    data()
        return 
            image: ''
        
    ,
    methods: 
        onFileChange(e) 
            let files = e.target.files || e.dataTransfer.files;
            if (!files.length)
                return;
            this.createImage(files[0]);
        ,
        createImage(file) 
            let reader = new FileReader();
            let vm = this;
            reader.onload = (e) => 
                vm.image = e.target.result;
            ;
            reader.readAsDataURL(file);
        ,
        upload()
            axios.post('/api/upload',image: this.image).then(response => 

            );
        
    

</script>

【讨论】:

是的,我想如果它对他有用,它也一定对我有用。我会做一个新项目,然后从头开始再试一次,看看与我的不同。 @Warrio 我在这里没有使用任何形式。 我使用您建议的代码创建了一个新项目。不幸的是,它再次返回 null。这是存储库的链接git clone git@bitbucket.org:warrio4/pr1.git 请看一下

以上是关于使用 vuejs 和 laravel 上传文件,无需表单的主要内容,如果未能解决你的问题,请参考以下文章

视频上传和流式传输(使用 Laravel VueJs 上传和显示所有类型的文件视频、图像、文档等)

在 vuejs 和 Laravel 中传递上传文件照片的值

Vue v-使用 Laravel 和 Vuejs 实现无数据显示

VueJS Laravel - 使用 Axios 上传图片发布错误:“给定数据无效”

使用 fetch API vuejs 上传文件返回 419 未知状态

文件路径空,Vue Js,Laravel,S3