文件上传及文件相关操作
前端文件上传有两种方式
二进制blob通过formData传输和转为base64传输
前端文件上传涉及到四种文件对象
files:通过input标签度过来的文件对象,前端对象不能传给后端
vue
1234567
<input type="file" name="file" @change="fileChage"/>
<script>
fileChage(e){
console.log(e.target.files[0])//files对象是自己创建好的,是一个数组,如果是单文件上传就是第0项
}
</script>
以下是对上传的文件进行文件类型与大小的限制方法
vue
123456789
<input type="file" name="file" @change="fileChage"/>
<script>
fileChage(e){
let file = e.target.files[0]
if(file.size > 10 * 24 * 24)alert("文件不能大于十兆")
if(file.type !== 'video/mp4')alert("文件必须是mp4")
}
</script>
blob:不可变的二进制内容,包含很多操作方法
fileReader:多用与把文件读取为某种形式,如base64,text文本
vue
1234567891011121314
<input type="file" name="file" @change="fileChage"/>
<script>
fileChage(e){
let file = e.target.files[0]
let blob = new Blob([file])//将file对象转为blob对象
let _sliceBlob = blob.slice(0,5000)//对blob进行切割
let _sliceFile = new File([_sliceBlob],"fileName.png")//将切割后的blob转为file
let fr = new FileReader()
fr.readAsDataURL(_sliceFile)//将切割后的文件转成base64
fr.onload = function() {//由于FileReader是异步执行的所以需要在这里面使用
console.log(fr.result)
}
}
</script>
注:缩略图功能就是将base64的图片展示出来,文本预览也是使用FileReader做
formData:用于和后端传输的对象
vue
123456789101112131415
<input type="file" name="file" @change="fileChage"/>
<button @click="submit">提交</button>
<script>
let _fileObj
fileChage(e){
let file = e.target.files[0]
_fileObj = file
}
const submit = () => {//由于formdata的作用主要是用来传递给后端,所以在提交的时候进行转换即可
let _formData = new FormData()
_formData.append("user","abcabc")//在给后端的信息中添加一个字段叫user,值为abcabc
_formData.append("file",_fileObj)//在给后端的信息中添加一个字段叫file,值为_fileObj
axios.post("/xx.com",_formData)//发送给后端
}
</script>
以上实现的就是单文件上传
文件的转化关系如下
多文件上传
原理就是将多个文件一个一个发送请求给后端
vue
1234567891011121314151617181920212223
//加上multiple属性支持一次选择多个文件,但是用户体验不好,所以我们需要在js中对其进行一些操作
<input type="file" name="file" @change="fileChage" multiple/>
<button @click="submit">提交</button>
<script>
let imgList = [];
let _fileObj;
fileChage(e){
if(e.target.files.lenth > 1){
imgList = imgList.concat(e.target.files)//当添加的文件数大于1的时候就将数组与之前的添加的拼接
}else{
imgList.push(e.target.files[0])//当添加的文件数只有1的时候就直接push
}
_fileObj = file
}
const submit = () => {//由于formdata的作用主要是用来传递给后端,所以在提交的时候进行转换即可
imgList.forEach((item) => {//遍历数组,将文件转为FormData
let _formData = new FormData()
_formData.append(item.name,item)
axios.post("/xx.com",_formData)//发送给后端
})
}
</script>
切片上传
原理:将大文件切成多片再转成formdata形式传给后端
vue
12345678910111213141516171819202122232425
<input type="file" name="file" @change="fileChage"/>
<div>{{ precent }}</div>//文件上传进度展示
<button @click="submit">提交</button>
<script>
let _fileObj
let precent //用来展示文件上传进度
fileChage(e){
let file = e.target.files[0]
_fileObj = file
}
const submit = () => {
let size = 2 * 1024 * 1024 //每片大小2Mb
let fileSize = _fileObj.size
let current = 0 //当前切到位置的基准值
while(current < fileSize){//只要还没切完就继续
let _formData = new FormData()
//每次发送2Mb的切片给后端
_formData.append(_fileObj.name,_fileObj.silce(current,current + size))
await axios.post("xxx.com",_formData)
precent = Math.min((current / fileSize) * 100, 100)//上传进度
current += size
}
}
</script>
后端方面:判断传过来的文件名一致,就拼接起来
