首先是这样,我在写一个表单上传页面的时候,结合elementeplus遇到了需要上传图片文件和视频文件的情况,一顿上网猛搜,经过一二十篇博客浏览下来,找到了三四篇可以参考,但是对于到底是上传file还是file.raw说法不一,于是我去查了FormData、file、file.raw、blob的文档,弄清楚了一些他们之间的关系。然后下面开始咔咔上知识点!
先说说formdata、blob、file、file.raw分别都是什么:
1.FormData:
FormData
接口提供了一种表示表单数据的键值对 key/value
的构造方式,并且可以轻松的将数据通过XMLHttpRequest.send() 方法发送出去,本接口和此方法都相当简单直接。如果送出时的编码类型被设为 "multipart/form-data"
,它会使用和表单一样的格式。
常用方法:
FormData.append()
向 FormData
中添加新的属性值,FormData
对应的属性值存在也不会覆盖原值,而是新增一个值,如果属性不存在则新增一项属性值。
let form = new FormData();form.append('title',videoForm.title);form.append('introduction',videoForm.introduction);form.append('file',formData.videoFile.raw);
其中的字段类型可以是 Blob、File 或者字符串:如果它的字段类型不是 Blob 也不是 File,则会被转换成字符串类。(但这里的file不是直接的file类型,formData 不支持直接将文件对象作为参数传入,需要经过一些转换比如用file.raw或者转换成Blob对象)
这里出现了Blob,这是个什么类型呢?
2.Blob
Blob
对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作。它经常会用来表示js数据格式的文件,但不一定只能是js文件。
常用方法:
Blob()构造函数。构造函数可以通过其他对象创建 blob。例如,用一个 JSON 字符串构造一个 blob:
const obj = {hello: 'world'};const blob = new Blob([JSON.stringify(obj, null, 2)], {type : 'application/json'});
3.File
再说到最常见的file类型,其实看完Blob我们就可以发现,file是一种特殊的Blob类型。file接口也继承了blob接口的所有属性,因为它太常见了,用法没有什么特别的,具体的就不细说啦~
api文档放在这儿了
4.file.raw
这个属性其实我是没找到什么官方文档的(有友友找到了欢迎留言评论哦,一起噶油!)
但是零零散散的搜索发现,它是一种二进制文件,可以通过formdata直接上传
所以说,开头那个问题,只要把上传的文件变成Blob或者取file.raw就可以了,bug解决!
用Blob和file.raw两种办法实现文件上传:
let form = new FormData();form.append('title',videoForm.title);form.append('introduction',videoForm.introduction);// 用file.raw上传视频文件form.append('file',formData.videoFile.raw);// 用Blob构造函数上传封面文件if(hasImg){ const blob=new Blob([formData.imgFile],{type:'png/jpeg/jpg'}); form.append('thumbnail',blob);}else{ form.append('thumbnail',null); }
我当时那个项目需要传一个视频和一张图片,如果一个用的转换为Blob一个用的file.raw,会发现f12的网络那儿都是显示的binary,(传到后端让他们再去处理就行了,我问了我们项目的后端,这两种都是可以正常查看文件的)
如果视频文件直接传入file,会出现400报错