下载文件的实现 js
就结果来论,这方面主要后端来做的,前端做的不多。(前端小伙伴们遇到这个问题可以松口气了),
但是开始做的时候我们都没接触过,所以我在前端用js做过一些类型的下载实现,
在此做一些总结和整理
先直接上最终实现的结果
前端代码
fileDownload(row){ // 下载文件
console.log(row.url)
var form = document.createElement('form');
document.body.appendChild(form);
form.style.display = "none";
form.action = `/api/oper-upload/api/medical/record/download?fileUrl=${row.url}`;
form.id = 'download';
form.method = 'post';
form.target= "_blank"
var newElement = document.createElement("input");
newElement.setAttribute("type","hidden");
form.appendChild(newElement);
form.submit();
},
代码解释
row.url是服务器端返回的文件url地址(本质上是文件在服务器端的位置,
由后端伙伴给出,或者自己上传文件调取接口返回的url地址)
form.target= "_blank" 表单提交 新页面打开
当前是以form表单提交的形式进行接口调用
注意事项
form表单没办法传递token信息,所以记得让后台伙伴放开token
后端代码
/**
* 根据给定的文件名进行下载
* Description: 从FTP服务器下载文件
* @param filename 要下载的文件名
* @return
*/
@RequestMapping("/downloadFileByOutputStream")
@ResponseBody
public String downloadFileByOutputStream(HttpServletResponse response, String filename) throws IOException {
logger.debug("下载ByOutputStream");
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect(host, port);
// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
ftp.login(username, password);// 登录
ftp.enterLocalPassiveMode(); //将ftp设置为被动模式。否则不成功。
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return "连接失败";
}
ftp.changeWorkingDirectory(publicFilePath);// 转移到FTP服务器目录
logger.debug("远程路径" + publicFilePath);
FTPFile[] fs = ftp.listFiles();
for (FTPFile ff : fs) {
logger.debug("远程文件名" + ff.getName());
if (ff.getName().equals(filename)) {
InputStream in = ftp.retrieveFileStream(ff.getName());
logger.debug(in.toString());
int len = 0;
byte[] buff = new byte[1024*1024];
response.reset();
response.setContentType("application/octet-stream");
//Name the file
response.addHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
// response.addHeader("Content-Length", out..ToString());
OutputStream out=response.getOutputStream(); //响应输出字节流
// OutputStream out = new PipedOutputStream();
while((len=in.read(buff))!=-1){
logger.debug("以字节流形式写出OutPutStream");
out.write(buff, 0, len);
out.flush();
}
in.close();
out.close();
return "成功";
}
}
ftp.logout();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return "失败";
}
后端我就不解析了,专业不对口,
好像是将文件作为OutputStream流作为回调结果,使用隐藏表单提交的方式对流进行回调
历程
如果你是doc xlxs ppt这种文档流,那么直接可以// window.open(row.url) // 就可以实现下载
// 如果是图片类型,且对大小无要求,就可以这么做
//但是这个样子会比原来的图片大上好多,而且同一变成了png格式
downloadByBlob(url,name) { // 图片文件转blob格式
let image = new Image()
image.setAttribute('crossOrigin', 'anonymous')
image.src = url
image.onload = () => {
let canvas = document.createElement('canvas')
canvas.style.display = 'none';
canvas.width = image.width
canvas.height = image.height
let ctx = canvas.getContext('2d')
ctx.drawImage(image, 0, 0, image.width, image.height)
canvas.toBlob((blob) => {
let url = URL.createObjectURL(blob)
this.download(url,name)
// 用完释放URL对象
URL.revokeObjectURL(url)
})
}
},
download(href, name) { // 图片文件下载
let eleLink = document.createElement('a')
eleLink.download = name
eleLink.style.display = 'none';
eleLink.href = href
eleLink.click()
eleLink.remove()
},
完结,致谢
参考:
解决下载ftp文件过程中,浏览器直接解析文件(txt,png等)的问题