使用HTML5 / Javascript来生成和保存文件

最近我一直在摆弄WebGL,并且得到了一个Collada阅读器。 问题是它很慢(Collada是一个非常详细的格式),所以我要开始转换文件到一个更容易使用的格式(可能是JSON)。 事情是,我已经有了parsingJavascript中的文件的代码,所以我不妨把它用作我的出口商呢! 问题是保存。

现在,我知道我可以parsing文件,将结果发送到服务器,并让浏览器从服务器请求文件作为下载。 但实际上服务器与这个特定的过程无关,那么为什么要涉及它呢? 我已经在内存中的所需文件的内容。 有没有什么办法,我可以提出使用纯JavaScript的下载用户? (我怀疑,但不妨问一下)

而且要清楚的是:我不想在没有用户知识的情况下访问文件系统! 用户将提供一个文件(可能通过拖放),脚本将转换文件在内存中,并提示用户下载结果。 就浏览器而言,所有这些都应该是“安全的”活动。

[编辑]:我没有提到它,所以回答“Flash”的海报是足够有效的,但我所做的一部分是试图强调可以用纯HTML5做什么…所以Flash是在我的情况下。 (尽pipe对于任何一个正在进行“真实”networking应用程序的人来说这是一个完全有效的答案)。事实是,除非我想涉及服务器,否则看起来我运气不好。 不pipe怎么说,还是要谢谢你!

好的,创build一个data:URI对我来说无疑是个窍门,这要感谢Matthew和Dennkster指出了这个select! 这里基本上是这样做的:

1)将所有内容转换为一个名为“内容”的string(例如,通过最初创build它或者通过读取已经构build的页面的标记的innerHTML)。

2)build立数据URI:

uriContent = "data:application/octet-stream," + encodeURIComponent(content); 

根据浏览器types等,会有长度限制,但是,例如Firefox 3.6.12至less可以工作到256k。 在Base64中使用encodeURIComponent进行编码可能会使事情变得更有效率,但是对于我来说这没问题。

3)打开一个新窗口,将其“redirect”到这个URI提示下载我的JavaScript生成页面的位置:

 newWindow = window.open(uriContent, 'neuesDokument'); 

而已。

简单的HTML5浏览器解决scheme

 function download(filename, text) { var pom = document.createElement('a'); pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); pom.setAttribute('download', filename); if (document.createEvent) { var event = document.createEvent('MouseEvents'); event.initEvent('click', true, true); pom.dispatchEvent(event); } else { pom.click(); } } 

用法

 download('test.txt', 'Hello world!'); 

HTML5定义了一个window.saveAs(blob, filename)方法。 目前不支持任何浏览器。 但是有一个名为FileSaver.js的兼容库,它将这个function添加到大多数现代浏览器(包括Internet Explorer 10+)中。 Internet Explorer 10支持用于Internet Explorer支持的FileSaver.js中的navigator.msSaveBlob(blob, filename)方法( MSDN )。

我写了一篇关于这个问题的更多细节的博客文章 。

 function download(content, filename, contentType) { if(!contentType) contentType = 'application/octet-stream'; var a = document.createElement('a'); var blob = new Blob([content], {'type':contentType}); a.href = window.URL.createObjectURL(blob); a.download = filename; a.click(); } 

看看Doug Neiner的Downloadify这是一个基于Flash的JavaScript界面​​来做到这一点。

Downloadify是一个小巧的JavaScript + Flash库,可以在浏览器中实时生成和保存文件,而无需与服务器交互。

保存大文件

长数据URI可能会导致浏览器的性能问题。 保存客户端生成的文件的另一个select是将其内容放在Blob(或File)对象中,并使用URL.createObjectURL(blob)创build下载链接。 这将返回一个可用于检索blob内容的URL。 blob存储在浏览器中,直到在URL上调用URL.revokeObjectURL()或者创build它的文档closures。 大多数Web浏览器都支持对象URL ,Opera Mini是唯一不支持它们的对象。

强制下载

如果数据是文本或图像,则浏览器可以打开文件,而不是将其保存到磁盘。 要使该文件在单击链接时被下载,可以使用download属性。 但是,并不是所有的Web浏览器都支持下载属性 。 另一种select是使用application/octet-stream作为文件的MIMEtypes,但是这会导致文件被呈现为二进制BLOB,如果您不指定文件名或者不能指定文件名,则该文件尤其会对用户不友好。 另请参阅“ 强制打开”“另存为…”popup式文本链接单击“HTML中的pdf ”。

指定一个文件名

如果blob是使用File构造函数创build的,那么也可以设置文件名,但只有less数浏览器(包括Chrome和Firefox) 支持File构造函数 。 文件名也可以被指定为download属性的参数,但是这受到很多安全性的考虑 。 Internet Explorer 10和11提供了自己的方法msSaveBlob来指定文件名。

示例代码

 data = []; data.push("This is a test\n"); data.push("Of creating a file\n"); data.push("In a browser\n"); properties = {type: 'plain/text'}; // Specify the file's mime-type. try { // Specify the filename using the File constructor, but ... file = new File(data, "file.txt", properties); } catch (e) { // ... fall back to the Blob constructor if that isn't supported. file = new Blob(data, properties); } url = URL.createObjectURL(file); document.getElementById('link').href = url; 
 <a id="link" target="_blank" download="file.txt">Download</a> 

简单解决scheme

 <a download="My-FileName.txt" href="data:application/octet-stream,HELLO-WORLDDDDDDDD">Click here</a> 

适用于所有现代浏览器(请参阅DEMO )。

ps href也可以用Javascript设置:
'data:application/octet-stream,' + encodeURIComponent(content);

你可以生成一个数据URI 。 但是,有一些浏览器特定的限制。

我用FileSaver( eligrey/FileSaver.html ),它工作得很好。
例如,我做了这个function来导出显示在页面上的日志。
你必须传递一个数组来实现Blob的实例化,所以我可能没有用正确的方式写这个,但是对我来说却是合适的。
以防万一,小心replace:这是使这个全球性的语法,否则将只会取代他遇到的第一个。

 exportLogs : function(){ var array = new Array(); var str = $('#logs').html(); array[0] = str.replace(/<br>/g, '\n\t'); var blob = new Blob(array, {type: "text/plain;charset=utf-8"}); saveAs(blob, "example.log"); } 

我发现了两个简单的方法适用于我。 首先,使用已经点击a元素并注入下载数据。 其次,用下载数据生成a元素,执行a.click()并再次删除它。 但是第二种方法只有在用户点击操作时才起作用。 (一些)浏览器阻止click()从其他上下文,如加载或超时后触发(setTimeout)。

 <!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <script type="text/javascript"> function linkDownload(a, filename, content) { contentType = 'data:application/octet-stream,'; uriContent = contentType + encodeURIComponent(content); a.setAttribute('href', uriContent); a.setAttribute('download', filename); } function download(filename, content) { var a = document.createElement('a'); linkDownload(a, filename, content); document.body.appendChild(a); a.click(); document.body.removeChild(a); } </script> </head> <body> <a href="#" onclick="linkDownload(this, 'test.txt', 'Hello World!');">download</a> <button onclick="download('test.txt', 'Hello World!');">download</button> </body> </html> 

这是一个链接到数据URI方法马修build议,它的Safari浏览器工作,但不好,因为我无法设置文件types,它被保存为“未知”,然后我必须再次去那里,并按顺序进行更改查看文件…

http://www.nihilogic.dk/labs/canvas2image/

你可以使用localStorage。 这是cookies的Html5等价物。 它似乎在Chrome和Firefox上工作,但在Firefox上,我需要上传到服务器。 也就是说,直接在我的家用电脑上testing不起作用。

我正在编写HTML5示例。 去http://faculty.purchase.edu/jeanine.meyer/html5/html5explain.html并滚动到迷宫之一。; 重build迷宫的信息使用localStorage存储。

我来到这篇文章寻找HTML5的JavaScript加载和处理XML文件。 它与旧的HTML和JavaScript相同吗?

如前所述, File API以及FileWriter和FileSystem API可以用于从浏览器选项卡/窗口的上下文中将文件存储在客户机器上。

不过,您应该了解后两种API的几个方面:

  • 这些API的实现目前只存在于基于Chromium的浏览器(Chrome和Opera)
  • 这两个API都是2014年4月24日从W3C标准轨道中脱离出来的,现在是专有的
  • 将来从实施的浏览器中删除(现在是专有的)API是可能的
  • 一个沙盒 (磁盘上的文件不能产生任何效果的位置)用于存储使用API​​创build的文件
  • 使用虚拟文件系统 (在浏览器中访问时不必以磁盘forms存在的目录结构)代表使用API​​创build的文件

下面是一些简单的例子,说明如何直接或间接地使用这些API:

烘焙食品 *

 bakedGoods.get({ data: ["testFile"], storageTypes: ["fileSystem"], options: {fileSystem:{storageType: Window.PERSISTENT}}, complete: function(resultDataObj, byStorageTypeErrorObj){} }); 

使用原始文件,FileWriter和FileSystem API

 function onQuotaRequestSuccess(grantedQuota) { function saveFile(directoryEntry) { function createFileWriter(fileEntry) { function write(fileWriter) { var dataBlob = new Blob(["Hello world!"], {type: "text/plain"}); fileWriter.write(dataBlob); } fileEntry.createWriter(write); } directoryEntry.getFile( "testFile", {create: true, exclusive: true}, createFileWriter ); } requestFileSystem(Window.PERSISTENT, grantedQuota, saveFile); } var desiredQuota = 1024 * 1024 * 1024; var quotaManagementObj = navigator.webkitPersistentStorage; quotaManagementObj.requestQuota(desiredQuota, onQuotaRequestSuccess); 

尽pipeFileSystem和FileWriter API不再处于标准轨道,但在某些情况下,它们的使用是合理的,在我看来,因为:

  • 来自未执行的浏览器供应商的重新兴趣可能会把它们放回去
  • 实施(铬)浏览器的市场渗透率很高
  • Google(Chromium的主要贡献者)并没有给出API的提交date

然而,“某些情况”是否包含您自己的情况是由您决定的。

* BakedGoods是由这个人保持在这里:)

这里是一个教程导出文件为ZIP:

开始之前,有一个库来保存文件,库的名称是fileSaver.js,你可以在这里find这个库。 让我们开始,现在,包括所需的库:

 <script src="ajax/libs/jszip/3.1.4/jszip.min.js" type="text/javascript"></script> <script type="text/javascript" src="https://fastcdn.org/FileSaver.js/1.1.20151003/FileSaver.js" ></script> 

现在复制这段代码,这段代码将会下载一个带有内容Hello World的文件hello.txt的zip文件。 如果一切工作正常,这将下载一个文件。

 <script type="text/javascript"> var zip = new JSZip(); zip.file("Hello.txt", "Hello World\n"); zip.generateAsync({type:"blob"}) .then(function(content) { // see FileSaver.js saveAs(content, "file.zip"); }); </script> 

这将下载一个名为file.zip的文件。 你可以在这里阅读更多: http : //www.wapgee.com/story/248/guide-to-create-zip-files-using-javascript-by-using-jszip-library