Javascript 下载文件保存到磁盘时的浏览器事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2343418/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 23:52:14  来源:igfitidea点击:

Browser event when downloaded file is saved to disk

javascriptbrowserdownloadsavedom-events

提问by David Pope

I have sensitive files to download to users, and each user is permitted to downloada given file exactly once. If the download fails, I want to permit the re-download, but not otherwise.

我有敏感文件要下载给用户,每个用户只能下载一次给定的文件。如果下载失败,我想允许重新下载,但不允许重新下载。

It's not sufficient to rely on logging/processing the file download requestat the server - I need to know deterministically when the file is complete and in place at the client, since many of my users work in an environment with frequent connectivity drops.

仅依靠在服务器上记录/处理文件下载请求是不够的 - 我需要确定性地知道文件何时完成并在客户端就位,因为我的许多用户在经常断开连接的环境中工作。

The most straightforward way for this to work would be if the browser exposed a "file saved" event from the Save As... dialog that could be wired to a JavaScript function on the download page (which could post back to the server). But, intuition suggests there might be security holes if browsers exposed this functionality, as it sneaks somewhat outside the sandbox. I'm not sure this is even possible.

最直接的方法是让浏览器从另存为...对话框中暴露一个“文件保存”事件,该事件可以连接到下载页面上的 JavaScript 函数(可以回发到服务器)。但是,直觉表明,如果浏览器公开此功能,则可能存在安全漏洞,因为它在沙箱之外有些偷偷摸摸。我不确定这是否可能。

I foundseveralotherquestionsin this area, but nothing about this problem specifically.

在这方面发现其他几个问题,但没有特别针对这个问题。

Any ideas?

有任何想法吗?

Edit:I should not have used the word "security" in the original question, sorry for triggering the red herrings.

编辑:我不应该在原始问题中使用“安全”这个词,抱歉触发了红鲱鱼。

Edit 2:My "security" phrasing misled folks into offtopic technical security issues, but both of you confirmed my suspicion that "no, there's no browser support for that." I'm marking the first commenter with the answer since his first sentence had what I was looking for. Thanks all.

编辑 2:我的“安全”措辞误导人们进入离题的技术安全问题,但你们两人证实了我的怀疑“不,浏览器不支持”。我正在用答案标记第一个评论者,因为他的第一句话就是我想要的。谢谢大家。

采纳答案by Martin

There's no such browser event in JavaScript and even if there was you can not trust the user's browser to provide security for you.

JavaScript 中没有这样的浏览器事件,即使有,您也不能相信用户的浏览器会为您提供安全性。

You're better off using a GUID to generate a unique URL for each download. You can then for example:

最好使用 GUID 为每次下载生成唯一的 URL。然后你可以例如:

  • let the URL be valid only for a specific time period
  • allow transfers only from a specific IP address associated with the unique URL
  • let your server-side code detect when the content for a unique URL has been fully transferred and then invalidate the URL.
  • 让 URL 仅在特定时间段内有效
  • 仅允许从与唯一 URL 关联的特定 IP 地址进行传输
  • 让您的服务器端代码检测唯一 URL 的内容何时已完全传输,然后使该 URL 无效。

Let me clarify the last bullet. Say you're using Java - you will in.read(buffer)and out.write(buffer)in a loop until EOF. If the client disconnects you will receive an IOExceptionduring out.write()and will be able to tell a successful download from an interrupted one. On other platforms, I'm sure there are ways to tell whether the connection was lost or not.

让我澄清最后一个要点。假设你使用的是Java -你会in.read(buffer)out.write(buffer)一个循环,直到EOF。如果客户端断开连接,您将收到一个IOException期间,out.write()并能够从中断的下载中分辨出成功下载。在其他平台上,我确信有办法判断连接是否丢失。

EDIT:You could actually fire a browser event using the trick outlined in the accepted answer of one of the questions you linked to. That would however not be a reliable solution to limit the number of downloads.

编辑:您实际上可以使用您链接到的问题之一的已接受答案中概述的技巧来触发浏览器事件。然而,这不是限制下载数量的可靠解决方案。

回答by rekna

This is a good solution:

这是一个很好的解决方案:

http://gruffcode.com/2010/10/28/detecting-the-file-download-dialog-in-the-browser/

http://gruffcode.com/2010/10/28/detecting-the-file-download-dialog-in-the-browser/

It basically works by setting a cookie in the reponse header of the downloaded file, so javascript periodically can check for the existence of this cookie...

它基本上是通过在下载文件的响应头中设置一个 cookie 来工作的,所以 javascript 可以定期检查这个 cookie 的存在......

回答by Seth Petry-Johnson

Why is it important that the file can be downloaded "exactly once"? Once the file is downloaded it could be copied, so is there really a security issue with letting the same userdownload the file more than once?

为什么文件可以“恰好一次”下载很重要?一旦文件被下载,它就可以被复制,那么让同一个用户多次下载文件真的存在安全问题吗?

If not, could you do something like this:

如果没有,你能不能做这样的事情:

  1. Generate a unique URL to download a given file. (Use a GUID to obsfucate if necessary)
  2. Associate that URL with USER INFO (browser type, IP address, etc) AND A TIME WINDOW. Only allow downloads from that user and during the window.
  3. The window should be long enough for the user to notice the transfer failed and to re-try once or twice, but no longer.
  1. 生成一个唯一的 URL 来下载给定的文件。(如有必要,使用 GUID 进行混淆)
  2. 将该 URL 与用户信息(浏览器类型、IP 地址等)和时间窗口相关联。只允许从该用户和窗口期间下载。
  3. 该窗口应该足够长,以便用户注意到传输失败并重试一两次,但不再重试。

The end result is:

最终结果是:

  1. You can be reasonably sure the file is only being downloaded by the intended recipient.
  2. You can be sure that recipient can only download the file during a short window.
  3. The same user could download the file more than once, but who cares? It's no different than making a local copy of the first file.
  1. 您可以合理地确定该文件仅由预期收件人下载。
  2. 您可以确定收件人只能在很短的时间内下载文件。
  3. 同一个用户可以多次下载文件,但谁在乎呢?这与制作第一个文件的本地副本没有什么不同。

If you're really worried about it, log each download request and run a scheduled report for files that were downloaded more than once. If anything looks fishy you can then examine security logs, talk to the user, etc.

如果您真的很担心,请记录每个下载请求并为多次下载的文件运行计划报告。如果有任何事情看起来可疑,您可以检查安全日志,与用户交谈等。