前端把一个文件上传到服务器上,一般有两种方案
- 第一种是通过二进制的blob对象 formData传输
- 第二种是通过base64上传
相关对象
1.files 通过input标签读过来的文件对象
2.blob 不可变的二进制内容,包含很多操作方法
3.formData 用于和后端传输的对象
4.fileReader 多用于把文件读取为某种形式,比如base64、text文本等
file对象(假设是单选状态)
<input type="file" name="file" @change="fileChange"></input>
fileChange(e){
let file = e.target.files[0] //拿到file对象
//判断文件的大小
if(file.size>10*1024*1024){
alert("文件不能大于十兆")
}
//判断文件的类型
if(file.type!=='video/mp4'){
alert("必须是mp4类型的文件")
}
console.log(file)
}
file对象与blob对象的互转
file对象其实是一种blob对象,是blob的子类
fileChange(e){
let file = e.target.files[0]
console.log(new Blob([file])) //转成blob对象
let _sliceBlob = new Blob([file]).slice(0, 5000) //切割blob
let _sliceFile = new File([_sliceBlob]) //创建了一个新的切割后的file对象
}
fileReader
fileReader对象是用来把我们的一些blob对象、file对象转成base64格式或者是文字格式
可以通过fileReader实现缩略图/文本预览
fileChange(e){
let file = e.target.files[0]
let _sliceBlob = new Blob([file]).slice(0, 5000) //切割blob
let _sliceFile = new File([_sliceBlob]) //创建了一个新的切割后的file对象
let fr = new FileReader()
fr.readAsDataURL(_sliceFile) //转为base64格式
fr.readAsText(_sliceFile) //转为文字格式
//文件读取不能直接拿到转化的结果,因为转化是一个异步的转化,需要监听onload的异步事件,才能获取转化后的结果
fr.onload = function(){
console.log(fr.result)
}
}
formData
上传的时候需要new FormData,异步上传二进制文件
<input type="file" name="file" @change="fileChange"></input>
<button @click="submit">提交</button>
async submit(){
let _formData = new FormData()
_formData.append("user", "aees")
_formData.append("file", _fileObj)
axios.post('/xx', _formData)
}
多文件上传
<input type="file" name="file" @change="fileChange"></input>
<button @click="submit">提交</button>
fileChange(e){
//多文件上传
if(e.target.files.length > 1){
this.imgList = this.imgList.concat(e.target.files)
}else{
this.imgList.push(e.target.files[0])
}
},
async submit(){
//多文件上传 循环上传
this.imgList.forEach((item)=>{
let _formData = new FormData()
_formData.append(item.name + "file", item)
axios.post('/xx', _formData)
})
}
切片上传
当文件很大的时候,就需要进行切片上传,把文件分割成多份,然后一份一份的上传
<input type="file" name="file" @change="fileChange"></input>
<button @click="submit">提交</button>
let _fileObj
fileChange(e){
//切片上传
this._fileObj = e.target.files[0]
},
async submit(){
//切片上传
let size = 2*1024*1024
let fileSize = _fileObj.size
let current = 0
//断点续传 4mb 记录当前的current传到哪了
localStorage.setItem(_fileObj.name, current)
while(current < fileSize){
let _formData = new FormData()
_formData.append(_fileObj.name, _fileObj.slice(current, current + size)) //后端通过传递的名字来拼接文件
//第一次切0-2兆,依次.... 上一个切片成功后,才能传下一个切片
await axios.post("http://localhost:4000/upload",_fileObj.slice(current, current + size))
current += size
}
}