java|form表单提交下载文件获取文件的是否下载完成

新人要做一个下载功能,为了良好的用户体验,要求点击下载之后弹出一个正在下载的提示框。
既然要有提示框,那下载完成之后肯定是要关闭提示框的,所以一开始我是用ajax来实现的,后面发现ajax根本不能获取到response的内容,所以无法完成下载。
之后我用from表单来提交,这个方法可是可以下载文件,但问题是不能获取到文件的下载状态,不能判断它是否完成下载然后好关闭提示框。
然后我又找了种方法,就是用XMLHttpRequest。代码如下:
前端页面代码:

下载

js代码
function downloadFile() { loading('正在下载...'); //这是我自定义的提示框 var url = "/sys/downloadFile"; var xhr = new XMLHttpRequest(); xhr.open('POST', url, true); xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xhr.responseType = "blob"; xhr.onload = function () { if (this.status === 200) { var blob = this.response; var reader = new FileReader(); reader.readAsDataURL(blob); reader.onload = function (e) { var headerName = xhr.getResponseHeader("Content-disposition"); var fileName = decodeURIComponent(headerName).substring(20); var a = document.createElement('a'); a.download = fileName; a.href = https://www.it610.com/article/e.target.result; $("body").append(a); // 修复firefox中无法触发click a.click(); closeLoading(); //关闭提示框 $(a).remove(); } } }; xhr.send(); }

后台代码:
response.setContentType("application/vnd.ms-excel; charset=utf-8"); response.setCharacterEncoding("UTF-8"); //XMLHttpRequest的跨域问题,设置为*号则表示允许任何域名跨域访问 response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "GET,POST"); response.setHeader("Content-Disposition", "attachment; filename="+filename,"UTF-8")); OutputStream out = response.getOutputStream(); //省略其他代码

写完这些后,确实可以下载了,没问题,然后我把代码提交到svn上去后,测试告诉我,有问题,点击下载的时候,浏览器控制台输出500错误,但是我在我自己的电脑上运行确实没问题,我又叫一个其他同事更新项目,运行下载也没有问题,我不知道为什么在服务器上运行就不行,我在网上找了一下午也没找到我这种情况的问题,没办法我只能不用这种方法了。然后找来找去,只能又用form提交下载。
最后,我终于找到一种用form提交可以获取文件的下载状态的办法。我参考的是这篇文章:https://blog.csdn.net/weixin_38661747/article/details/80754258
代码如下:
js代码:
function downloadFile() { try{ var downloadToken = +new Date(); //设置一个时间戳发送到后台 var url = "/sys/downloadFile?downloadToken="+downloadToken; loading('正在下载...'); //这个提示框是我自定义的提示框 var form = $("
"); form.attr("action", url); form.attr("method", "post"); form.attr("enctype", "multipart/form-data"); $("body").append(form); form.submit(); form.remove(); function checkToken() { //前端实时监测时间戳和后台设置的cookie值是否相等,相等就说明文件下载成功,就可以关闭提示框 var token = getCookie("downloadToken"); if (token && token == downloadToken) { clearTimeout(downloadTimer); closeLoading(); //关闭提示框 } } var downloadTimer = setInterval(checkToken, 1000); }catch(e){ alert(e.name + ": " + e.message); } } //获取后台设置的cookie值 function getCookie(cookieName) { var strCookie = document.cookie; var arrCookie = strCookie.split("; "); for(var i = 0; i < arrCookie.length; i++){ var arr = arrCookie[i].split("="); if(cookieName == arr[0]){ return arr[1]; } } return ""; }

后台代码:
//将时间戳设置到cookie中 Cookie cookie = new Cookie("downloadToken", downloadToken); cookie.setPath("/"); cookie.setMaxAge(-1); response.addCookie(cookie); response.setContentType("application/vnd.ms-excel; charset=utf-8"); response.setCharacterEncoding("UTF-8"); response.setHeader("Content-Disposition", "attachment; filename="+filename,"UTF-8")); OutputStream out = response.getOutputStream(); //省略其他代码

【java|form表单提交下载文件获取文件的是否下载完成】写完之后测试,可以没问题,然后提交,最后并没有再出现问题(松了一口气)
就一个下载弄了我花了我两天时间,当然单单是下载的话肯定很简单,主要是要监听文件的下载状态,好加个提示框和关闭提示框,不然我也不用改这么多次代码了。
还有一个问题就是XMLHttpRequest下载为什么本地下载没问题但是上传到公司的服务器运行就不行,知道的话可以告诉我哟~

    推荐阅读