如何在下载文件后隐藏动画gif?
在执行某些服务器端Java代码并且客户端从Web服务器获取HTTP响应而不使用Ajax时,有没有办法让动画gif图像消失?
我使用以下Struts2提交按钮:
显示动画gif图像的方法:
function myJsFunction(){ $("#containerWithGifImage").fadeIn("fast"); }
消除动画gif图像的方法(但我不知道,如何在没有Ajax的情况下调用它):
function myJsFunction2(){ $("#containerWithGifImage").fadeOut("fast"); }
现在gif出现了,但是在执行webserver上的java代码之后它并没有消失。
你的问题(这个和另一个 )都是XY问题的例子。
在寻找特定技术,技术或黑客之前,请先明确定义您的目标:
目标
- 下载文件而不移动到其他页面;
- 同时,显示一个指标(进度条,动画gif,叠加等…);
- 下载文件后,隐藏指示器。
解决方案
将您的触发器绑定到javascript函数, 如下所述 :
download
在你的Javascript函数中:显示指标,启动计时器以检查下载是否结束(然后隐藏指标),然后下载文件:
function myJsFunction(){ $("#containerWithGifImage").fadeIn("fast"); // Show the indicator setInterval(function(){ $.ajax({ url : "/isDownloadFinished.action", type : "GET", success : function(data,textStatus,jqXHR) { $("#containerWithGifImage").fadeOut("fast"); // Hide the indicator },error : function(jqXHR, textStatus, errorThrown) { console.log("Download is still in progress, do nothing..."); } }); }, 1000); // Check every second if download has finished window.location='/download.action'; // Start the download }
Download.action必须在会话中放入一个指示下载已开始的属性,并在结束时进行更新。
由于使用stream
结果,您将控制对浏览器的响应(因此在完成后无法运行代码),您可以直接写入响应,然后返回NONE
, 如下所述 :
public class Download extends ActionSupport implements SessionAware, ServletResponseAware { @Setter private Map session; @Setter private HttpServletResponse response; public String execute(){ ServletOutputStream os = null; try { session.put("DOWNLOAD_STATUS","active"); response.setContentType("myContentType"); response.addHeader("Content-Disposition", "attachment; filename=\"foo.bar\""); os = response.getOutputStream(); IOUtils.copy(getMyFileInputStreamSomeHow(), os); } finally { IOUtils.closeQuietly(os); session.put("DOWNLOAD_STATUS","finished"); } return NONE; } }
您还可以让浏览器通过指定Content-Length
响应头( response.setHeader("Content-Length", 1337);
)来为您绘制进度条, 如此处所述 ,您还可以在其中查看类似的机制以防止并发下载。
在IsDownloadFinished.action中 ,您需要检查会话属性。 我它不存在或与完成不同,这意味着下载尚未开始,或仍在进行中,因此什么都不做。 否则,返回一个成功的httpheader,它将使你的jQuery $ .ajax函数运行success:
回调。 您可以使用httpHeader
或json
, 如下所述 :
@Results({ @Result(name = ActionSupport.SUCCESS, type="httpheader", params = {"status", "200"}), @Result(name = ActionSupport.ERROR, type="httpheader", params = {"error", "500"}) }) public class IsDownloadFinished extends ActionSupport implements SessionAware { @Setter private Map session; public String execute(){ if ("finished".equals(session.get("DOWNLOAD_STATUS")) { session.remove("DW_STATUS"); return SUCCESS; } return ERROR; } }
这个问题有不同的解决方案,我向你展示了最简单的解决方案。
更优雅和复杂的解决方案将涉及长期请求和Comet技术 (读取:WebSocket),但我想您可以从此启动示例开始使用轮询计时器,根据您的需求进行自定义,并最终在更多时候进行演变对论点感到满意。