如何在Nuxt.js中使用FormData结合Vuetify实现正确的文件上传?
问题原因
- Vuetify的
v-file-input组件默认返回值为文件数组,即使未开启多选配置,绑定的v-model值也是单元素数组格式,你直接将数组作为文件传入FormData,会导致服务端接收到的内容不是二进制文件流,自然打开就提示损坏。 - 部分开发者会手动给上传请求加
Content-Type: multipart/form-data请求头,这会导致浏览器无法自动生成请求所需的boundary分隔符,也会导致FormData解析失败。 - 如果你的请求拦截器有全局配置
transformRequest或者统一设置了JSON序列化规则,也会把FormData格式错误转义,导致内容损坏。
修复方案
修改后的代码如下:
<template> <div> <v-file-input label="Select a file" accept="image/*" v-model="myFile"> 上传到S3的文件 </v-file-input> <v-btn class="ma-2" color="secondary" @click="uploadFile"> 上传 </v-btn> </div> </template> <script> export default { data() { return { myFile: null, } }, methods: { async uploadFile() { // 先做非空校验 if (!this.myFile || this.myFile.length === 0) return // 取数组第一个元素,获取真实的File二进制对象 const targetFile = this.myFile[0] let formData = new FormData() formData.append("files", targetFile, targetFile.name); try { await this.$http.put(myURL, formData, { // 不要手动设置Content-Type,浏览器会自动生成带boundary的正确请求头 // 如果axios全局配置了请求体转JSON,这里单独关掉转义逻辑 transformRequest: [data => data] }) } catch (e) { console.error('上传失败', e) } } } } </script>
校验方法
可以在发送请求前打印formData.get('files'),确认输出是File对象而不是数组,就能避免绝大多数上传损坏问题。
内容的提问来源于stack exchange,提问作者Sébastien Serre
相关产品推荐
相关产品推荐

