如何让 Web 浏览器下载存储在 JavaScript 字符串中的文件?

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

How to get a web browser to download a file that is stored in a JavaScript String?

javascriptiframedownloadlocal

提问by Sean N.

I've been able to write JavaScript to cause the browser to download a file from a remote server using code like this:

我已经能够编写 JavaScript 来使浏览器使用如下代码从远程服务器下载文件:

var iframe = document.createElement("iframe");
iframe.style.display = "none";
iframe.src = "filename.zip"
document.body.appendChild(iframe);

Which works great. However, now I have a different situation where the contents of the file are stored in a string in my JavaScript on the browser side and I need to trigger a download of that file. I've tried replacing the third line above with this, where 'myFileContents' is the string containing the actual bytes of the file:

这很好用。但是,现在我有一种不同的情况,文件的内容存储在浏览器端的 JavaScript 中的字符串中,我需要触发该文件的下载。我试过用这个替换上面的第三行,其中 'myFileContents' 是包含文件实际字节的字符串:

iframe.src = "data:application/octet-stream;base64," + Base64.encode(myFileContents);

This gets the file downloaded, but the file name is lost. In Chrome the file name is just 'download'. Also I've read that there are limitations to the file size allowed in some browser versions.

这将下载文件,但文件名丢失。在 Chrome 中,文件名只是“下载”。我还读到某些浏览器版本中允许的文件大小有限制。

Is there a way to achieve this? Using JQuery would be OK. The solution needs to support any file type - zip, pdf, csv, png, jpg, xls, etc...

有没有办法实现这一目标?使用 JQuery 就可以了。该解决方案需要支持任何文件类型 - zip、pdf、csv、png、jpg、xls 等...

回答by Mathijs Flietstra

In some newer browsersyou can use the new HTML5 download attributeon the atag to achieve this:

一些较新的浏览器中,您可以在标签上使用新的HTML5 下载属性a来实现此目的:

var a = document.createElement('a');
a.download = "filename.txt";
a.href = "data:application/octet-stream;base64," + Base64.encode(myFileContents);
a.click();

For a future solution you could look into the HTML5 FileSystem API, but this API is not currently supported in most of the major browsers. It might not be of much use to you except for that it might provide you with another way to store the files locally if you would be OK with that. But it doesn't store the files on the users locally accessible file system, you would have to develop your own browser based interface for your users to interact with the files. Downloading the files from the HTML5 file system to the users local file system would in any case again be done using the new download attribute on an atag, which would then refer to a location in the HTML5 file system instead of referring to an online location.

对于未来的解决方案,您可以查看HTML5 FileSystem API,但目前大多数主要浏览器都不支持此 API 。它可能对您没有多大用处,除非它可能为您提供另一种在本地存储文件的方法,如果您愿意的话。但它不会将文件存储在用户本地可访问的文件系统上,您必须开发自己的基于浏览器的界面,以便您的用户与文件进行交互。在任何情况下,将文件从 HTML5 文件系统下载到用户本地文件系统将再次使用a标签上的新下载属性完成,然后将引用 HTML5 文件系统中的位置,而不是引用在线位置。

To do this with an iframeelement you would have to somehow set the Content-Dispositionrequest header on the iframe to inline; filename="filename.txt"using client side JavaScript, I don't think it is possible to do this, most likely because of security issues. If you really don't have any other option, you could kill the download speed performance by sending the string to the server using AJAX and then downloading it from there again with the right request headers set.

要使用iframe元素执行此操作,您必须以某种方式将Content-Dispositioniframe 上的请求标头设置为inline; filename="filename.txt"使用客户端 JavaScript,我认为这是不可能的,很可能是因为安全问题。如果您真的没有任何其他选择,您可以通过使用 AJAX 将字符串发送到服务器,然后使用正确的请求标头设置再次从那里下载它来降低下载速度性能。