Java安全后端返回文件流方式
作者:Aimyone
这篇文章主要介绍了Java安全后端返回文件流方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
Java安全后端返回文件流
起由
业务流程:上传文件——服务器保存文件——根据路径访问文件
这种根据路径定位文件,并对文件进行查看的方式对文件安全有很大威胁,一旦知道其他文件的路径,很有可能会造成文件泄露
改进
所以,当前端访问文件的时候,发出请求并携带token,后端验证token,确认为合法用户之后,放行
根据请求路径执行后端的代码(后端代码逻辑:根据路径读取文件,输出文件流,响应给前端)
配置文件
配置上存文件的保存路径
代码
import org.apache.commons.io.IOUtils; @Value("${file.ectdreport-folder}") private String ectdReportFolder; @Transactional(rollbackFor = Exception.class) public void lookReport(String id, HttpServletResponse response) throws Exception { String url = ectdReportFolder + id + "/file1.html"; File file = new File(url); if (!file.exists()) { throw new Exception("文件不存在");//抛出文件不存在的 } response.setContentType("text/html"); FileInputStream fis = null; OutputStream outputStream = response.getOutputStream(); try { fis = new FileInputStream(file); //将读取流拷贝到输出流中 IOUtils.copy(fis, outputStream); //清空缓存的读取流,保证数据完整性 response.flushBuffer(); } catch (IOException e) { e.printStackTrace(); throw new Exception("解析失败"); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } if (outputStream != null) { outputStream.close();//输出流关闭 } } }
后端返回文件流,前端怎么导出、下载
工作中肯定有很多导出excel、下载文件这种功能。一般都是后端做好,我们去请求对应的接口就行了,前端还需要做一些处理就可以实现导出、下载功能了。
第一步:在请求的时候做些一些处理
我们在请求的时候 需要定义responseType【响应类型】为blob类型,如果是post请求还需要在请求头里携带Content-Type: 'multipart/form-data'
// 在请求的时候做一些处理 // get请求 markMownLoad = (id) => axios('get',`URLxxxxxx?fileId=${id}`,{ responseType: 'blob', headers:{ 'Content-Type': 'multipart/form-data' } }) // post请求 markMownLoads = (id) => axios('post',`URLxxxxxx?fileId=${id}`,{ responseType: 'blob', headers:{ 'Content-Type': 'multipart/form-data' } })
第二步:向后端发请求
在请求之前,我们先封装一个解码下载的一个方法,方便我们请求成功后调用
function downLoadXls (res) { const fileNames = res.headers['content-disposition'] if(fileNames) { //解码 const fileName = decodeURIComponent(fileNames.match(/=(.*)$/)[1]) // 处理返回的文件流 const content =res.data const blob = new Blob([content],{ type: "application/octet-stream; charset=utf-8" }); if('download' in document.createElement('a')) { //非IE下载 const a = document.createElement('a') //创建一个a标签 a.download = fileName //指定文件名称 a.style.display = 'none' //页面隐藏 a.href = URL.createObjectURL(blob) // href用于下载地址 document.body.appendChild(a) //插到页面上 a.click() //通过点击触发 URL.revokeObjectURL(a.href) //释放URL 对象 document.body.removeChild(a) //删掉a标签 }else{ //IE10 + 下载 navigator.msSaveBlob(blob,fileName) } } }
这个时候发请求就可以了
// 发请求 把后端返回的传过去解码,然后实现导出、下载 markMownLoads(参数).then(res => downLoadXls(res))
咱们来看一下后端返回的数据时什么样子的
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。