基于vue框架怎样实现文件上传下载,具体代码是什么
Admin 2022-09-20 群英技术资讯 328 次浏览
1.所用技术
前端:Vue + Axios
后端:Springboot + SpringMVC
后端代码
只需要使用MultipartFile类配合RequestBody注解即可
@PostMapping("your/path") public ResultData courseCoverUpload(@RequestBody MultipartFile file){ /** your service */ }
前端代码
Axios上传需要设置头部,使用FormData封装文件对象
//file为文件对象 function upload(file){ //请求头设置 const header={"Content-type":"multipart/form-data"} let formData=new FormData(); //用file作为key没问题,其他没试过 formData.append("file",file); //这里request封装过,也可以直接使用axios.post() request.post(`path`,formData,{headers:header}).then(res=>{ //your serivce }) }
如若使用element-ui的upload组件,可以选择自定义上传方法(好处是可以再请求头中加入token)
<el-upload class="upload-demo" :auto-upload="false" action :http-request="uploadFile" ref="upload" > <el-button type="text">点击上传</el-button> </el-upload>
上述uploadFile正是上传时的回调函数,使用方法如下
function uploadFile(param){ //param中的file才是真正的文件体,用于传入axios上传方法的参数 upload( param.file ) },
后端代码
将@RequestBody换成==@RequestPart==注解,并再注解中加入接收时的识别key即可同时接受文件和其他Json参数
@PostMapping("up") public ResultData uploadTest( @RequestPart("file") MultipartFile file, @RequestPart("other") Map<String,String> props ){ return ResultData.success().data("file_size",file.getSize()).data("others",props); }
前端代码
function uploadFile(file_body,other_json){ //头信息不变 const header={"Content-type":"multipart/form-data"} //依旧用FormData作数据封装 let form_data=new FormData(); //此处的key要与后端统一,这里都使用file form_data.append("file",file_body) //再封装其他参数时需要使用Blob,[]不要错,type一定要加 form_data.append( "other",new Blob([JSON.stringify(other_json)],{type:"application/json"})) //这里request封装过,也可以直接使用axios.post() request.post(url,form_data,{headers: header}).then(rs=>{ console.log(rs); }) }
使用axios下载文件最恶心之处就在于前后端请求头还有解析格式要匹配,否则就会出现跨域或者文件流出错等问题。
后端代码
和返回json数据不同,返回文件流需要使用HttpServletResponse类的输出流将文件流逐一打印出去,这里选择用过滤器处理请求,也可以使用Controller
编写接收前端请求的过滤器
public class FileFilter implements Filter , InputOutputUtil { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { /** 本次后端默认前端使用Get请求进行下载,如若get需要传递参数可以用getParameter方式获取 HttpServletRequest request = (HttpServletRequest) servletRequest; System.out.println(request.getParameter("a")); */ //获取文件输出流,这里是读取本地的 File f= new File("file_path"); InputStream inpurStream = new FileInputStream(file); /** 如果文件资源在其他服务器上(比如阿里云的OSS),可以用以下代码获取文件流 URLConnection urlConn = new URL("URL_PATH").openConnection(); urlConn.connect(); InputStream inputStream = urlConn.getInputStream(); */ //输出方法,放在了自己编写的InputOutputUtil中 this.writeFile(servletResponse,"security_key.jpg",inputStream); } }
辅助输出的接口
public interface InputOutputUtil { //输出文件时用 default void writeFile(ServletResponse servletResponse, String fileName,InputStream inputStream) throws IOException { HttpServletResponse response = (HttpServletResponse) servletResponse; //设置返回的头信息 response.setContentType("application/octet-stream"); response.setCharacterEncoding("UTF-8"); response.addHeader("Content-disposition", "attachment;filename=\""+fileName+"\""); //跨域处理 response.setHeader("Access-Control-Expose-Headers","Content-Disposition"); response.setHeader("Access-Control-Allow-Origin","*"); response.setHeader("Access-Control-Allow-Methods","GET,POST,PUT,DELETE"); response.setHeader("Access-Control-Allow-Headers","*"); response.setHeader("Access-Control-Max-Age","false"); response.setHeader("Access-Control-Allow-Credentials","10"); //获取输出流 ServletOutputStream outputStream=response.getOutputStream(); //将文件流逐一放入输出流中打印给前端 byte[] bs1=new byte[1024]; int length; while((length=inputStream.read(bs1))!=-1){ outputStream.write(bs1,0,length); } //关流操作 outputStream.close(); inputStream.close(); } }
前端代码
使用axios的get方法发起请求
function downloadFile(url,param=null){ //设置头信息 let config = {responseType:'blob'} //如若前端有参数就加入一下 if (param!=null) config["params"]=param //带着头信息和请求参数发起请求 request.get(url,config).then(res=>{ //如若成功了,开始拆箱 //获取filename,这里使用的是正则表达式,关联 辅助输出接口 的第9行 let file_name=res.headers["content-disposition"].match(/filename=\"(\S*)\"/)[1] //data中装的是文件体,需要使用Blob流可以下载 let blob = new Blob([res.data]) //网上最常用的下载方法 let downloadElement = document.createElement('a') let href = window.URL.createObjectURL(blob); //创建下载的链接 downloadElement.href = href; downloadElement.download = file_name; //下载后文件名 document.body.appendChild(downloadElement); downloadElement.click(); //点击下载 document.body.removeChild(downloadElement); //下载完成移除元素 window.URL.revokeObjectURL(href); //释放blob对象 }) }
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
在本篇文章里小编给大家整理的是一篇关于js定时器出现第一次延迟的原因及解决方法,对此有需要的朋友们可以学习下。
这篇文章主要介绍了javascript的基础交互详解,文章通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
目录1.ES5常用:利用for嵌套for,然后splice去重2.ES6常用:Set去重3.indexOf去重4.sort()排序5.对象属性不能相同(不建议)6.includes()7.hasOwnProperty8.filter9.利用递归去重10.Map去重11.reduce+includes1.ES5常用:利用
转换方法:1、利用split()方法将字符串转为字符数组;2、遍历字符数组,利用charCodeAt()和toString()方法将每个字符元素转为二进制值;3、使用join()方法拼接数组元素,转为完整的二进制值即可。
使用typescript类型来实现快排详情 目录 前言 元组快排 实现逻辑 实现数字的大小比较 实现 A 是否 小于或等于 B 实现 A 是否 大于或等于 B 实现Filter 优化Filter 重构数字的大小值比较 重构Filter 实现快排 测试快排 优化:负数 负数的判断 字符串转数字 获取负数的值 完善获取绝对值 重构数字的大小比较 重构快排 测试快排V2 前言 本文执行环境typescript,版本4.7.4 不使用typescript的计算能力,通过类型来实现快排 元组快排 能否将元组 [3, 1, 2, 4] 通过泛型转换成
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008