Vue.js - 当标头中使用 multipart/form-data 时,axios 中的文件上传验证失败
Posted
技术标签:
【中文标题】Vue.js - 当标头中使用 multipart/form-data 时,axios 中的文件上传验证失败【英文标题】:Vue.js - validation fails for file upload in axios when multipart/form-data used in header 【发布时间】:2020-04-15 14:44:01 【问题描述】:我正在构建一个 Laravel+Vue.js SPA(单页应用程序),使用 BootstrapVue、VeeValidate 和 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
..
让我试试这个
你说得对,好像是。
【参考方案1】:
我想使用FormData API 会起作用。
下面是一些例子:
How to post a file from a form with Axios axios post request to send form data
【讨论】:
【参考方案2】:我建议在提交表单后使用VeeValidation
来验证您的表单。
这是非常简单和最甜蜜的验证方法。
您可以从这里安装它。 VeeValidation Link
【讨论】:
以上是关于Vue.js - 当标头中使用 multipart/form-data 时,axios 中的文件上传验证失败的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Boot 中使用 multipart/form-data 处理没有 Content-Disposition 标头的 POST
为啥我的“multipart/form-data”标头不能阻止发送预检 (OPTIONS) 请求?
Node.js、Vue.js 和 Passport.js。 .isAuthenticated() 总是返回 false? Axios 标头可能吗?
由于不允许的预检标头,Vue.js 前端与 Flask 后端 CORS 问题交互
批处理请求必须具有“Content-Type”标头/“multipart/mixed”作为媒体类型
已解决 - CORS、OPTIONS 和 PreFlight 问题 在 Vue.js 中使用 Axios 使用 REST API