pc端实现文件上传与下载
前后端进行文件交互,主要形式为文件的上传与下载。
(1)上传的主要形式为前端通过文件上传插件将文件通过文件流形式传递到后端,后端进行处理,保存至目标地址。
(2)下载的主要形式为前端访问后台下载地址,实现文件下载,然后弹出下载框,进行保存行为。
本次主要介绍文件的上传功能实现
【前端实现】:
前端实现文件上传的方法有很多,具体总结如下:
方法一、form表单和input上传
<form action='uploadFile.php' enctype="multipart/form-data" type='post'>
<input type='file'>
<input type='hidden' name='userid'>
<input type='hidden' name='signature'>
<button>提交</button>
</form>
这种方式比较经典的前后端文件传输方式,这种方式兼容性较好,妹传递一个数据就要新建一个input,value属性中为需要传递的数据。
优点:兼容所有的浏览器,但无法得知何时上传结束,并且上传结束后,页面会发生跳转。每上传一个元素内容,就要创建一个input,导致dom结构复杂冗余。
优化:
<form action='uploadFile.php' enctype="multipart/form-data" type='post' target="uploader1">
<input type='file'>
<button>提交</button>
</form>
<ifrmae name='upload' id='uploader1'></iframe>
创建一个空的iframe,设置form控件的target属性为iframe控件的id值,就可以指定位置进行上传,提交数据后依旧停留在当前页。
【注意】:
form的target属性可以规定在何处打开action,即指定的页面。
【优势】:
1、禁止页面跳转。
2、后端返回的内容可以在iframe中读到。
方法二、使用formData上传
html部分:
<input type='file'>
js部分:
var formData = new FormData();
formData.append("userid", userid);
formData.append("signature", signature);
formData.append("file", file); //file是blob数据
//在用ajax发送formData到服务器即可,注意一定要是post方式上传
【注意】:
这种方式与使用form表单上传有异曲同工之处,只是这里使用了ajax上传,可以知道上传是否成功,完成时间等。
方法三、使用fileReader读取文件数据进行上传
var fr = new FileReader();
fr.readAsDataURL(file);
fr.onload = function (event) {
var data= event.target.result; //此处获得的data是base64格式的数据
img.src = data;
ajax(url,{data} ,function(){})
}
上面获得的data可以用来实现图片上传前的本地预览,也可以用来发送base64数据给后端然后返回该数据块对应的地址。
【补充】:前端实现文件上传的插件很多,但背后的思路都是一样的,最常用的还是表单上传的方式,插件推荐bootstrap文件上传插件(建议自行网上寻找)。
【后端实现】:
主要逻辑:文件流通过http协议进行文件传输交流,一个文件一个文件进行上传,多文件也是实现单文件依次上传,然后进行处理
/*
文件上传
*/
@PostMapping("/File/upload")
@ResponseBody
public AjaxResult upload(MultipartHttpServletRequest request,HttpServletResponse response) {
/*
多个文件上传的逻辑也是一个文件一个文件的访问后台,上传文件
*/
//获得当前项目的根路径
//方法一、
//String basepath = ClassUtils.getDefaultClassLoader().getResource("").getPath();
//方法二、
//String path = ResourceUtils.getURL("classpath:").getPath();
File newfile=null;
try{
newfile =new File(ResourceUtils.getURL("classpath:").getPath());
}
catch (FileNotFoundException e) {
}
// 获得文件:
MultipartFile file = request.getFile("file");
//获得文件名
String filename=file.getOriginalFilename();
/*
实现文件按文件后缀名进行分类
*/
//字符串截取获取后缀名 不含.
String type= filename.substring(filename.lastIndexOf(".")+1);
//根据文件的类型,指定文件的保存路径
String path="";
//根据文件后缀名进行判断文件类型
switch (type){
//文本文件保存
case "txt":
case "docx":
case "doc":
path=FileTool.txt_path;
break;
//图片文件保存
case "bmp":
case "png":
case "gif":
case "webp":
case "jpeg":
case "jpg":
case "psd":
path=FileTool.image_path;
break;
//pdf文件保存
case "pdf":
path=FileTool.pdf_path;
break;
//文件类型未知,存入文本文件夹
default:
path=FileTool.txt_path;
}
if (file != null) {
//获取当前文件名
String fileName = file.getOriginalFilename()==null?"":file.getOriginalFilename();
//获取保存文件的时间
String currentDateFolder = DateFormatUtils.format(new Date(), "yyyyMMdd");
//拼接保存文件地址 暂存到与项目所在的文件夹下
//String destFilePath = "D:/uploads" + File.separator + currentDateFolder + File.separator+fileName;
//String destFilePath = "D:/uploads"+File.separator+path+File.separator+currentDateFolder+fileName;
String destFilePath = newfile.getAbsolutePath()+File.separator+path+File.separator+currentDateFolder+fileName;
try {
File destFile = new File(destFilePath);
//若指定的文件夹不存在,则创建指定文件夹
if (!destFile.getParentFile().exists()) {
destFile.getParentFile().mkdirs();
}
file.transferTo(destFile);
// 这里直接返回的服务器上的物理地址,项目中需要根据实际情况自行处理
return toAjax(1);
} catch (IOException e) {
// TODO 异常处理
return toAjax(-1);
}
}
//ApiResult为封装的接口统一返回泛型类,项目中根据实际情况处理
return toAjax(-1);
}