java 浏览器下载完成事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1524487/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Browser download complete event
提问by laura
We've been looking for a while for an answer to this, but haven't found a solution.
我们一直在寻找这个问题的答案,但没有找到解决方案。
We have a web server, which allows the user to download files (pdfs), which are dynamically-generated and served from servlets. We'd like to know when a download has completed (and how: was it successful, did it fail, did the user cancel?).
我们有一个 Web 服务器,它允许用户下载文件 (pdf),这些文件是动态生成的并由 servlet 提供。我们想知道下载何时完成(以及如何完成:是否成功、是否失败、用户是否取消?)。
Is there a way to know this without user input? These files are relatively small so no progress-bar functionality is needed, but we need some sort of "end-hook" which reports back when the download has finished. Is this possible?
有没有办法在没有用户输入的情况下知道这一点?这些文件相对较小,因此不需要进度条功能,但是我们需要某种“end-hook”在下载完成时进行报告。这可能吗?
[edit] What capability would there be on the browser-side that can detect end-of-download and report back to the server via ajax?
[编辑] 浏览器端有什么功能可以检测下载结束并通过 ajax 报告给服务器?
采纳答案by David Rabinowitz
Unless you get a network error, you cannot know. The only way is to have the browser to send a second event to the server (using AJAX) to acknowledge the download was completed successfully.
除非您遇到网络错误,否则您无法知道。唯一的方法是让浏览器向服务器发送第二个事件(使用 AJAX)以确认下载已成功完成。
回答by ZZ Coder
You can get a pretty good idea from the server which is connected to the browser directly (the endpoint of TCP connection). The server will get IO error when user cancels download or encounters any network problem. So if you can run the server directly (without proxies). You can do something like this,
您可以从直接连接到浏览器的服务器(TCP 连接的端点)中获得一个不错的主意。当用户取消下载或遇到任何网络问题时,服务器将出现 IO 错误。因此,如果您可以直接运行服务器(无需代理)。你可以做这样的事情,
try {
response.setContentType("application/pdf");
response.setContentLength(bytes.length);
ServletOutputStream ouputStream = response.getOutputStream();
ouputStream.write(bytes, 0, bytes.length);
ouputStream.flush();
ouputStream.close();
logger.info("PDF " + fileName + " sent successfully");
} catch (Exception e) {
logger.error("PDF " + fileName + " error: " + e.getMessage());
throw e;
}
However, there is still a small chance that the user may not see the PDF in browser after successful download. ACK from browser will be best approach. You can't do that if PDF is displayed by browser directly. You have to use some kind of Javascript PDF viewer and add a call back to server when it's displayed.
但是,用户在成功下载后,仍有很小的可能在浏览器中看不到 PDF。来自浏览器的 ACK 将是最好的方法。如果浏览器直接显示 PDF,则不能这样做。您必须使用某种 Javascript PDF 查看器,并在显示时向服务器添加回调。
回答by Mohsen
User cancelling can sometimesbe detected in a servlet. Using Tomcat for example, try to stream a large file to the client, and then cancel the download. You can see the stacktrace of the exception in logs/catalona.out. I'm not sure, however, that this can be handled in servlet itself or a lower level (inside catalina).
有时可以在 servlet 中检测到用户取消。以Tomcat为例,尝试将一个大文件流式传输到客户端,然后取消下载。您可以在 logs/catalona.out 中看到异常的堆栈跟踪。但是,我不确定这是否可以在 servlet 本身或更低级别(在 catalina 内部)中处理。
There is a preloading approach (sure with event listener facility) usually used to download images. It's up to the browser to download the whole PDF or not if it detects it as an unsupported image, but it worths giving a try. Hereis an example.
有一种预加载方法(当然有事件侦听器功能)通常用于下载图像。如果浏览器将其检测为不受支持的图像,则取决于浏览器是否下载整个 PDF,但值得一试。这是一个例子。
Another solution would be to implicitly download the PDF using <object>or <embed>tags, and using their onload event listener. Not that this only works if an ActiveX or some sort of PDF file association is done in the browser, and probably won't work if user doesn't have a PDF viewer. Hereis an example demonstrating this (see assisted solution: 11/21/04 08:22 AM, ID: 12638846).
另一种解决方案是使用<object>或<embed>标签隐式下载 PDF ,并使用它们的 onload 事件侦听器。并不是说这仅在浏览器中完成 ActiveX 或某种 PDF 文件关联时才有效,如果用户没有 PDF 查看器,则可能不起作用。这是一个演示此示例的示例(请参阅辅助解决方案:11/21/04 08:22 AM,ID:12638846)。
Mohsen
莫森
回答by Jim Downing
Even though the files are small, if you use the setContentLengthmethod of ServletResponsethe user will be able to distinguish between an error and a good download, and their browser's download manager will tell them when it's complete.
即使文件很小,如果您使用用户的setContentLength方法ServletResponse将能够区分错误和良好的下载,并且他们的浏览器的下载管理器会在下载完成时告诉他们。
回答by Ben Rowe
The browser natively does not handle this but you could use google gears to handle the download request (it would fire a success event when the download has been completed).
浏览器本身不处理此问题,但您可以使用 google gears 来处理下载请求(下载完成后会触发成功事件)。
回答by Serxipc
If you can insert an image field in your documents, the image href can point back to your server to confirm that the user has opened the pdf document.
如果您可以在文档中插入图像字段,则图像 href 可以指向您的服务器以确认用户已打开 pdf 文档。
I haven't tried this myself but looking at the last page of this adobe docseems possible.
我自己还没有尝试过,但查看这个 adobe doc的最后一页似乎是可能的。
If you are using Itext it does not support the image fields, but you can use a pdf template with the image field to build your documents and add the javascript to assign the url to the image field.
如果您使用的是 Itext,它不支持图像字段,但您可以使用带有图像字段的 pdf 模板来构建文档并添加 javascript 以将 url 分配给图像字段。

