赞
踩
利用formData上传文件遇到的错误及解决方案
真的吐了!!!!!!!!!!!!!!!!!!!!
一个bug改了要一个周!!!!!!
啥都感觉没问题,却出现了问题。前端el-upload+formData传文件,后端用multipartFile解析文件,但是收到的图片数组为null!!!!!!!!!
handleChange(file, fileList) {
this.form.file.push(file);
}
2.构造file-list中元素,将其push进file-list数组
handleChange(file, fileList) {
//查阅element-plus文档,发现file-list数组中元素需要满足的对象格式为{name:'xxx',url:'xxxx'}
let reader = new FileReader();
reader.readAsDataURL(file.raw);
reader.onload = (e) => {
this.form.file.push({ name: file.raw.name, url: e.target.result });
}
this.file.push(file.raw);
fileList = this.form.file;
}
header:{
'Content-Type': 'multipart/form-data;boundary=<calculated when request is sent>'
}
默认submit,数据以formData的形式发送给后端
formData中的键值对{key:value}中的key是表单元素中的name值,value是表单属性中的value值(vue中可以为v-model绑定的值)
表单外的附带data如何随着表单一起默认提交(如不用在表单中填写的user)
解决方案:附带数据可以放在一个隐藏的input中,submit时跟着一起提交
<el-input name="user" v-model="user" v-show="false"/>
el-upload组件的name默认为file,前后端接口需对应
默认submit执行后会刷新并跳转页面,没有办法调试
解决方案:用iframe接收跳转的页面,使得原页面只刷新不跳转
<el-form
ref="form"
:model="form"
label-width="80px"
enctype="multipart/form-data"
method='post'
action='接口的url'
target='myFrame'
>
</el-form>
<!-- 接受跳转的iframe -->
<iframe name='myFrame' style='display:none;'></iframe>
发现的契机:
1.起初我是直接把handleChange(file, fileList) 中的file加入文件数组this.form.file中,查看发出去的请求时,发现formData中的文件数组的类型是[object Object]
于是我打印this.form.file数组发现这是一个proxy数组,真正的文件在proxy.raw中,也就是说真正的文件是file.raw;
2.接着我就试着将handleChange(file, fileList) 中file.raw的File数组append进formData发送给后端,此时请求中文件数组的类型变成了[object File]。我真的以为没问题了,但是后端仍然解析不了[苦涩.jpg]
3.自定义提交不行了,只能再试试表单默认submit。当我试了很多次终于用iframe接收跳转的页面,解决了原页面总跳转无法调试的问题时,我看到了默认submit发出的请求中文件数组的格式是(binary)。
4.我终于搞懂了原因,我应该把文件以(binary)的形式传给后端解析。
疑惑:为什么formData.append(‘file’,文件数组)之后不是binary形式呢?
(此间我们做了无数尝试,用fileReader读文件转成Blob,binaryString…都失败了)
解决:直接向formData中添加文件数组,文件不能被分转成(binary),只有每次添加一个文件时该文件才会被转成(binary)传输给后端。
故多次向formData中同一个键名下添加文件即可
https://blog.csdn.net/weixin_43249665/article/details/100084637
<el-form ref="form" :model="form" label-width="80px" enctype="multipart/form-data" > </el-form-item> <el-input name="user" v-model="user" v-show="false"/> </el-form-item> <el-form-item label="上传图片"> <el-upload list-type="picture-card" action="#" :limit="9" :on-change="handleChange" :on-remove="handleRemove" :on-exceed="handleExceed" :auto-upload="false" :multiple="false" :file-list="form.file" accept="image/png,image/gif,image/jpg,image/jpeg" > <i class="el-icon-plus"></i> </el-upload> </el-form-item> <div style="width: fit-content; margin: 0 auto 20px"> <el-button type="primary" @click="handleSubmit()">提交</el-button> <el-button @click="dialogVisible = false">取消</el-button> </div> </el-form>
form:{
user;
file:[];//保存fileList
}
file[];//
handleChange(file, fileList) { //查阅element-plus文档,发现file-list数组中元素需要满足的对象格式为{name:'xxx',url:'xxxx'} let reader = new FileReader(); reader.readAsDataURL(file.raw); reader.onload = (e) => { this.form.file.push({ name: file.raw.name, url: e.target.result }); } this.file.push(file.raw); fileList = this.form.file; }, onCancel() {//取消 if (confirm("该操作将放弃所有表单内容。确定取消填写吗?")) close(); }, handleRemove(file) { // 1.从filelist数组中,找到图片对应的索引值 const i = this.form.files.findIndex(x => x.name === file.name) // 2.调用splice方法,移除图片信息 this.form.files.splice(i, 1); const j = this.files.findIndex(x => x.name === file.name) this.files.splice(j, 1); }, handleExceed() { this.$message( { message: '图片数不能超过9张', type: 'warning' } ) }, handleSubmit() { let formData = new FormData(); for (let i = 0; i < this.file.length; i++) { formData.append('file', this.file[i]); } formData.append('user', this.user); this.axios({ url: '······', method: 'post', data: { formData }, headers: { 'Content-Type': 'multipart/form-data;boundary=<calculated when request is sent>' } }).then( (res) => {} }, function (err) { console.log(err) }
ps:在此特别感谢后端调试的朋友们还有帮我改前端代码的学长。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。