前端有关文件上传下载操作

文件上传

文件上传有两种形式(传给后端的文件形式)

  • 变成blob通过formData搭载传输(二进制blob传输)
  • 转为base64直接传输(简便,但是后端需要解码,时间长),通过fileReader搭载

相关对象:

files(blob的一个子类):通过input标签读取过来的文件对象(属于前端的方法,没办法直接传给后端)

blob:不可变的二进制内容,包含很多操作方法(new Blob([file]) 直接将file放进去可以得到一个Blob对象)

formData:用于和后端传输的对象,可以用来搭载blob对象来将文件传输给后端,用于和后端传输的对象

fileReader:多用于把文件(二进制)读取转化为某种形式,如文本text,base64,然后可以直接把base64的文件传给后端(看后端传递数据需求),或者自己前端需要把一些文件转为base64格式

单文件上传



let imgurl=ref("")

function f1(e){
  //获取到file对象
  let file=e.target.files[0]
  // 限制文件大小
  if(file.size>10000000){
    alert("文件不能大于100kb")
    e.target.value=""
    return;
  }
  // 限制文件后缀名
  let name=file.name.split(".")[1]
  if(name!=="dll"){
    alert("文件类型必须是dll")
    e.target.value=""
    return
  }
  // 新建formData对象
  let form=new FormData()
  // 通过append方法加入文件
  form.append("file",file)
  //form作为数据传给后端就可以了
  axios.post("/xx",form)

  // 新建fileReader
  let fileReader=new FileReader()
  fileReader.readAsDataURL(file)//读成base64形式
  // 当文件读取完成后执行
  fileReader.onload=function(){
    imgurl.value=fileReader.result//读取后的结果
    // 如果上传的文件是图片,这个读取后的结果可以赋值给img里的src,可以在页面中展示缩略图
    axios.post("/xx",{base64:fileReader.result})
  }
}

多文件上传(循环的单文件上传,拿到每一个文件)

给input框加个属性multiple(需要用户在弹出的选择文件里按住ctrl键选择多个文件,用户不好操作),

所以这里需要定义一个数组,存放每次选择文件时,将选择的文件保存下来,让用户多次选择文件添加

let imgArr=reactive([])
let base64Arr=reactive([])



function f2(e){
  // 存储多个文件
  let fileList=e.target.files
  for(let i=0;i{
    form.append(file.name,file)
  })
  axios.post("/xx",form)
}

大文件切片和断点续传

通过slice方法将大文件进行切片=>记录当前切到哪一位=>后端拼接切片

slice方法是blob对象的方法,但是file对象是blob对象的子类

两个参数——切分的起点和终点

let file=e.target.files[0]

let _sli=file.slice(0,10000) ( 这个切片是一个blob对象格式)

let per=ref('')
function f3(e){
  let file=e.target.files[0];
  let fileSize=file.size//文件大小
  let current=0;//记录当前切到哪一位
  let size=2*1024*1024//设置每次切片大小为2M
  
  // 判断本地有没有保存上传进度(也就是断点续传,将上次上传的进度保存下来)
  let localPer=parseInt(localStorage.getItem(file.name))
  // 如果有,就将当前current改为本地保存的开始进度
  if(localPer){
    current=localPer
  }
  
  // 如果当前切点位小于文件总大小,就一直切片进行上传
  // 当当前切点大于文件大小,说明上传完毕
  while(currrent

文件下载

后端直接以二进制的形式将文件传过来

文件下载有三种方式

直接打开下载地址

直接通过后端地址就能直接下载(无法命名,只适用于get直接返回blob接口)

window.open("/xx/xx")

利用a标签的download(推荐)

需要先了解几个概念

  • createObjectURL——把blob对象的内存地址,以url形式给出(因为接口传递的数据是二进制形式,通过blob去接收传过来的二进制文件,这里就可以把blob对象给到createObjectURL,然后以url形式给出,然后这个url就可以通过a标签去加载
let res1 = await downloadPro({ path: res.data.url })
            .then((response: any) => {
              let blob = new Blob([response], { type: "application/zip" });
              let url = window.URL.createObjectURL(blob);
              const link = document.createElement("a"); // 创建a标签
              link.href = url;
              // link.download = "文件名.zip"; // 重命名文件
              link.click();
              URL.revokeObjectURL(url); // 释放内存
              ElMessage.success("下载成功!");
            })
            .catch((error: any) => {});
  • msSaveBlob——IE不支持a标签下载,用的是msSaveBlob方案(如果浏览器是IE,直接把blob给msSaveBlob,直接下载)
  • a标签的download属性——表明该a标签的行为是下载,并说明文件名

流程 :

首先要按blob请求接口;

有msSavaBlob的情况下直接用msSavaBlob下载;

没有msSavaBlob的情况下,需要创建文件本地url(createObjectURL)=>创建a标签=>将创建的url赋值给a标签的href=>设置download下载的文件名=>模拟点击a标签;

// 直接调用接口获取到的是二进制形式文件,需要将响应类型设置为blob形式
axios.get('/xx/xx',{responseType:"blob"}).then((res)=>{
  // 判断有没有msSaveBlob,有就代表是一个IE浏览器
  if(window.navigator.msSaveBlob){
    window.navigator.msSaveBlob(res.data,
    {type:"文件类型"},
    "test.ppt"
                              )
  }else{
    // 创建出一个本地url地址
    URL.createObjectURL(res.data)
    // 创建标签
    let link=document.createElement("a")
    // 设置href
    link.href=blobURL
    // 设置下载下来的文件名
    link.download="test.ppt"
    // 设置不显示
    link.style.display="none"
    // 模拟点击
    link.click()
    // 销毁创建的url
    URL.revokeObjectURL(blobURL)
  }
})

file-saver现有的库,简单方便

import {saveAs} from 'file-saver'

axios.get("/xx/xx",{responseType:"blob"}).then((res)=>{

saveAs(res.data,"filename.ppt")

})

你可能感兴趣的:(前端,javascript)