在内存中创build一个文件供用户下载,而不是通过服务器
有什么办法可以在客户端创build一个文本文件,并提示用户下载它,而不需要与服务器进行任何交互? 我知道我不能直接写他们的机器(安全和所有),但我可以创build并提示他们保存吗?
您可以使用数据URI。 浏览器支持各异 见维基百科 。 例:
<a href="data:application/octet-stream;charset=utf-16le;base64,//5mAG8AbwAgAGIAYQByAAoA">text file</a>
八位字节stream是强制下载提示。 否则,它可能会在浏览器中打开。
对于CSV,您可以使用:
<a href="data:application/octet-stream,field1%2Cfield2%0Afoo%2Cbar%0Agoo%2Cgai%0A">CSV Octet</a>
试试jsFiddle演示 。
简单的HTML5浏览器解决scheme
function download(filename, text) { var element = document.createElement('a'); element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); element.setAttribute('download', filename); element.style.display = 'none'; document.body.appendChild(element); element.click(); document.body.removeChild(element); }
form * { display: block; margin: 10px; }
<form onsubmit="download(this['name'].value, this['text'].value)"> <input type="text" name="name" value="test.txt"> <textarea name="text"></textarea> <input type="submit" value="Download"> </form>
上述所有的例子在Chrome和IE中都能正常工作,但在Firefox中却失败了。 请考虑在主体上添加一个锚点并点击后将其移除。
var a = window.document.createElement('a'); a.href = window.URL.createObjectURL(new Blob(['Test,Text'], {type: 'text/csv'})); a.download = 'test.csv'; // Append anchor to body. document.body.appendChild(a); a.click(); // Remove anchor from body document.body.removeChild(a);
以上所有解决scheme都不适用于所有浏览器。 以下是IE 10+,Firefox和Chrome(以及没有 jQuery或任何其他库)的最终作品:
save: function(filename, data) { var blob = new Blob([data], {type: 'text/csv'}); if(window.navigator.msSaveOrOpenBlob) { window.navigator.msSaveBlob(blob, filename); } else{ var elem = window.document.createElement('a'); elem.href = window.URL.createObjectURL(blob); elem.download = filename; document.body.appendChild(elem); elem.click(); document.body.removeChild(elem); } }
请注意,根据您的情况,您可能还想在移除elem
后调用URL.revokeObjectURL 。 根据URL.createObjectURL的文档 :
每次调用createObjectURL()时,都会创build一个新的对象URL,即使您已经为同一个对象创build了一个对象。 当你不再需要它们时,每一个都必须通过调用URL.revokeObjectURL()来释放。 当文档被卸载时,浏览器会自动释放这些文件; 但是,为了获得最佳的性能和内存使用情况,如果有明确卸载它们的安全时间,则应该这样做。
我很高兴使用FileSaver.js 。 它的兼容性非常好(IE10 +和其他一切),使用起来非常简单:
var blob = new Blob(["some text"], { type: "text/plain;charset=utf-8;", }); saveAs(blob, "thing.txt");
以下方法适用于IE11 +,Firefox 25+和Chrome 30+:
<a id="export" class="myButton" download="" href="#">export</a> <script> function createDownloadLink(anchorSelector, str, fileName){ if(window.navigator.msSaveOrOpenBlob) { var fileData = [str]; blobObject = new Blob(fileData); $(anchorSelector).click(function(){ window.navigator.msSaveOrOpenBlob(blobObject, fileName); }); } else { var url = "data:text/plain;charset=utf-8," + encodeURIComponent(str); $(anchorSelector).attr("download", fileName); $(anchorSelector).attr("href", url); } } $(function () { var str = "hi,file"; createDownloadLink("#export",str,"file.txt"); }); </script>
在Action中看到这个: http : //jsfiddle.net/Kg7eA/
Firefox和Chrome支持用于导航的数据URI,这允许我们通过导航到数据URI来创build文件,而IE为了安全目的不支持它。
另一方面,IE有API保存blob,可以用来创build和下载文件。
这个解决scheme直接从tiddlywiki(tiddlywiki.com)的github仓库中提取。 我几乎在所有的浏览器中都使用了tiddlywiki,它的作用就像一个魅力:
function(filename,text){ // Set up the link var link = document.createElement("a"); link.setAttribute("target","_blank"); if(Blob !== undefined) { var blob = new Blob([text], {type: "text/plain"}); link.setAttribute("href", URL.createObjectURL(blob)); } else { link.setAttribute("href","data:text/plain," + encodeURIComponent(text)); } link.setAttribute("download",filename); document.body.appendChild(link); link.click(); document.body.removeChild(link); }
Github回购: 下载保护模块
在IE10上工作的解决scheme:(我需要一个csv文件,但它足以将types和文件名更改为txt)
var csvContent=data; //here we load our csv data var blob = new Blob([csvContent],{ type: "text/csv;charset=utf-8;" }); navigator.msSaveBlob(blob, "filename.csv")
如果你只是想将string转换为可供下载,你可以尝试使用jQuery。
$('a.download').attr('href', 'data:application/csv;charset=utf-8,' + encodeURI(data));
var element = document.createElement('a'); element.setAttribute('href', 'data:text/text;charset=utf-8,' + encodeURI(data)); element.setAttribute('download', "fileName.txt"); element.click();
截至2014年4月,FileSytem APIs可能不会在W3C中标准化。 任何人看着blob解决scheme应该谨慎,我想。
HTML5的岩石抬头
FileSytem API上的W3C邮件列表
基于@Rick的答案是非常有帮助的。
如果您想以这种方式共享stringdata
则必须查看stringdata
:
$('a.download').attr('href', 'data:application/csv;charset=utf-8,'+ encodeURI(data));
`对不起,我不能评论@瑞克的答案,因为我目前在StackOverflow中的低信誉。
编辑build议被分享和拒绝。
你甚至可以做一个比URI更好的方式 – 使用Chrome,你也可以build议文件的名称,正如本篇博客中所述,在使用URI时命名下载 。
正如前面提到的, filesaver是一个在客户端使用文件的格式包。 但是,处理大文件不好。 StreamSaver.js是一个替代解决scheme(指向FileServer.js)处理大型文件:
const fileStream = streamSaver.createWriteStream('filename.txt', size); const writer = fileStream.getWriter(); for(var i = 0; i < 100; i++){ var uint8array = new TextEncoder("utf-8").encode("Plain Text"); writer.write(uint8array); } writer.close()
如果文件包含文本数据,我使用的技术是将文本放入一个textarea元素,并让用户select它(点击textarea然后按Ctrl-A),然后复制,然后粘贴到文本编辑器。
它实际上是可能的 – 使用Flash。
您可以使用JS生成内容,然后初始化一些闪存variables,或者在闪存电影中执行所有操作。
请看一下这个重要的评论。