【问题标题】:Vue.js - validation fails for file upload in axios when multipart/form-data used in headerVue.js - 当标头中使用 multipart/form-data 时,axios 中的文件上传验证失败
【发布时间】:2020-04-15 14:44:01
【问题描述】:

我正在构建一个 Laravel+Vue.js SPA(单页应用程序),使用 BootstrapVueVeeValidate 和 axios 作为 HTTP 客户端。

在 axios 内部,当我在 headers 中使用 multipart/form-data; boundary=${uploadForm._boundary} 作为 Content-Type 然后 Laravel Controller 方法中的所有验证都失败

但如果我在header 中使用'content-type': 'multipart/form-data',则验证工作除了file 输入字段。在 Laravel 控制器方法中,file 字段变为空。

这发生在组件EditProfile.vue 中。里面的内容是:

<template>
<ValidationObserver ref="form" v-slot="{ passes }">

        <div id="registration_form">

            <div id="form_title" class="text-center">Edit Your Profile</div>
            <div v-html="result" class="result text-center"></div>


            <b-form name="uploadForm" @submit.prevent="passes(onSubmit)" @reset="resetForm"  enctype="multipart/form-data">


                <ValidationProvider vid="name" rules="required|min:2" name="name" v-slot="{ valid, errors }">
                    <b-form-group
                            label="User Name:"
                            label-for="exampleInput1"

                    >
                        <b-form-input
                                type="text"
                                disable-leading-trailing-space
                                v-model="name"
                                plaintext
                                :state="errors[0] ? false : (valid ? true : null)"
                                placeholder="Enter your name"
                        ></b-form-input>
                        <b-form-invalid-feedback id="inputLiveFeedback">{{ errors[0] }}</b-form-invalid-feedback>
                    </b-form-group>
                </ValidationProvider>



                <ValidationProvider vid="photo" rules="required" name="photo" v-slot="{ valid, errors }">
                    <b-form-group
                            label="Photo:"
                            label-for="exampleInput1"
                    >


                        <b-form-file

                                accept="image/x-png,image/gif,image/jpeg"
                                v-model="file"
                                :state="Boolean(file)"
                                placeholder="Choose a file or drop it here..."
                                drop-placeholder="Drop file here..."
                                @change="onFileChange" enctype="multipart/form-data"
                        ></b-form-file>
                        <b-form-invalid-feedback id="inputLiveFeedback">{{ errors[0] }}</b-form-invalid-feedback>
                        <div class="mt-3">Selected file: {{ file ? file.name : '' }}</div>

                        <!-- Plain mode -->
                        <!--<b-form-file v-model="file2" class="mt-3" plain></b-form-file>
                        <div class="mt-3">Selected file: {{ file2 ? file2.name : '' }}</div>-->

                        <div id="preview">
                            <img v-if="url" :src="url" />
                        </div>

                    </b-form-group>
                </ValidationProvider>





                <b-button type="submit" variant="primary">Submit</b-button>
                <b-button type="reset" variant="danger">Reset</b-button>
            </b-form>

        </div><!-- end of id registration_form-->
    </ValidationObserver>
</template>

在 JS 部分,我有:

<script>

  
    import { ValidationObserver, ValidationProvider } from "vee-validate";

     export default {
        name: "EditProfile",
        props: {

        },

        components: {
            ValidationObserver,
            ValidationProvider
           

        },
        data: () => ({

            name: "",
            photo:"",
            file:"",
            url:"",  
            result:''

        }),

        methods: {
            onFileChange(e) {
                this.file = e.target.files[0];
                this.url = URL.createObjectURL(this.file);
            },
        onSubmit() {
                console.log("Form submitted yay!");


                this.result='<span class="wait">Please wait ...</span>';

                axios.post('/update_profile_now',
                    {
                       name: this.name,
                       photo:this.file

                    }, // the data to post
                    {


                        headers: {
      
                            //Accept: 'application/json',

                           'Content-Type':  `multipart/form-data; boundary=${uploadForm._boundary}`
                            
                        }



                    })
                    .then(response => {
      
                        if(response.data.success){

                            this.result='<span class="succes">Registration completed !!</span>';
                        }else{

                            this.$refs.form.setErrors(response.data.errors);

                            this.result='<span class="error">Invalid data !!</span>';
                        }


      

                    })
                    .catch(error => {

                        if(typeof error !=="undefined"){

                            console.log(error);
                        }

                    });

                //    .finally(() => this.loading = false)
            },
            resetForm() {
                this.name = "";
      
                this.result='';

                requestAnimationFrame(() => {
                    this.$refs.form.reset();
                });
            }
        }
    };

</script>

在相应的 Laravel 控制器方法中我有:

 public function update_profile_now(Request $request)
    {

        
        $rules = array(

            'name' => 'required | min:4',
            'photo'=> 'image|mimes:jpeg,png,jpg|max:2048'
        );

        $validator = Validator::make(Input::all(), $rules);

        // Validate the input and return correct response
        if ($validator->fails())
        {
            return Response::json(array(
                'success' => false,
                'errors' => $validator->getMessageBag()->toArray()

            ), 200); 
        }

        //file uploading code goes here 

        return Response::json(array('success' => true), 200);




   }

我想要的是其中包含file 输入的表单将被提交,然后在文件上传和其他工作之后从该方法发送 JSON 响应。

那么正确的标题应该是什么,还是我需要采取任何其他方式?

【问题讨论】:

  • 您正在尝试将this.file 发布为json 有效负载,但使用multipart MIME 类型.. 我想它不会这样工作.. 看看@ 987654323@ 并将name 字段也作为多部分字段(而不是json)传递
  • ' 将名称字段也作为多部分字段(而不是 json)传递' - 你是什么意思?该怎么做?
  • 好吧,我假设您需要为此使用FormData#append..
  • 让我试试这个
  • 你说得对,好像是。

标签: laravel vue.js axios bootstrap-vue vee-validate


【解决方案1】:

【讨论】:

    【解决方案2】:

    我建议在提交表单后使用VeeValidation 来验证您的表单。

    这是非常简单和最甜蜜的验证方法。

    您可以从这里安装它。 VeeValidation Link

    【讨论】:

      猜你喜欢
      • 2014-03-07
      • 1970-01-01
      • 2015-10-23
      • 1970-01-01
      • 1970-01-01
      • 2020-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多