Javascript 如何在内存中创建一个文件供用户下载,而不是通过服务器?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3665115/
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
How to create a file in memory for user to download, but not through server?
提问by Joseph Silber
Is there any way I can create a text file on the client side and prompt the user to download it, without any interaction with the server? I know I can't write directly to their machine (security and all), but can I create and prompt them to save it?
有什么方法可以在客户端创建一个文本文件并提示用户下载它,而无需与服务器进行任何交互?我知道我不能直接写入他们的机器(安全和所有),但是我可以创建并提示他们保存它吗?
采纳答案by Matthew Flaschen
You can use data URIs. Browser support varies; see Wikipedia. Example:
您可以使用数据 URI。浏览器支持各不相同;参见维基百科。例子:
<a href="data:application/octet-stream;charset=utf-16le;base64,//5mAG8AbwAgAGIAYQByAAoA">text file</a>
The octet-stream is to force a download prompt. Otherwise, it will probably open in the browser.
octet-stream 是强制下载提示。否则,它可能会在浏览器中打开。
For CSV, you can use:
对于 CSV,您可以使用:
<a href="data:application/octet-stream,field1%2Cfield2%0Afoo%2Cbar%0Agoo%2Cgai%0A">CSV Octet</a>
Try the jsFiddle demo.
试试jsFiddle 演示。
回答by Matěj Pokorny
Simple solution for HTML5 ready browsers...
适用于 HTML5 浏览器的简单解决方案...
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>
Usage
用法
download('test.txt', 'Hello world!');
回答by Ludovic Feltz
All the above solutions didn't work in all browsers. Here is what finally works on IE 10+, Firefox and Chrome (and withoutjQuery or any other library):
以上所有解决方案都不适用于所有浏览器。以下是最终适用于 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);
}
}
Note that, depending on your situation, you may also want to call URL.revokeObjectURLafter removing elem. According to the docs for URL.createObjectURL:
请注意,根据您的情况,您可能还想在删除.revokeObjectURL后调用URL.revokeObjectURLelem。根据URL.createObjectURL 的文档:
Each time you call createObjectURL(), a new object URL is created, even if you've already created one for the same object. Each of these must be released by calling URL.revokeObjectURL() when you no longer need them. Browsers will release these automatically when the document is unloaded; however, for optimal performance and memory usage, if there are safe times when you can explicitly unload them, you should do so.
每次调用 createObjectURL() 时,都会创建一个新的对象 URL,即使您已经为同一个对象创建了一个。当您不再需要它们时,必须通过调用 URL.revokeObjectURL() 来释放它们中的每一个。当文档被卸载时,浏览器会自动释放这些;但是,为了获得最佳性能和内存使用,如果有可以明确卸载它们的安全时间,则应该这样做。
回答by naren
All of the above example works just fine in chrome and IE, but fail in Firefox. Please do consider appending an anchor to the body and removing it after click.
以上所有示例在 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);
回答by Daniel Buckmaster
I'm happily using FileSaver.js. Its compatibility is pretty good (IE10+ and everything else), and it's very simple to use:
我很高兴使用FileSaver.js。它的兼容性非常好(IE10+和其他所有东西),并且使用起来非常简单:
var blob = new Blob(["some text"], {
type: "text/plain;charset=utf-8;",
});
saveAs(blob, "thing.txt");
回答by dinesh ygv
The following method works in IE11+, Firefox 25+ and Chrome 30+:
以下方法适用于 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>
See this in Action: http://jsfiddle.net/Kg7eA/
在行动中看到这个:http: //jsfiddle.net/Kg7eA/
Firefox and Chrome support data URI for navigation, which allows us to create files by navigating to a data URI, while IE doesn't support it for security purposes.
Firefox 和 Chrome 支持数据 URI 导航,这允许我们通过导航到数据 URI 来创建文件,而 IE 出于安全目的不支持它。
On the other hand, IE has API for saving a blob, which can be used to create and download files.
另一方面,IE 具有用于保存 blob 的 API,可用于创建和下载文件。
回答by Danielo515
This solution is extracted directly from tiddlywiki's (tiddlywiki.com) github repository. I have used tiddlywiki in almost all browsers and it works like a charm:
该解决方案直接从 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 repo: Download saver module
Github repo: 下载保存模块
回答by Dzarek
Solution that work on IE10: (I needed a csv file, but it's enough to change type and filename to txt)
适用于 IE10 的解决方案:(我需要一个 csv 文件,但将类型和文件名更改为 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")
回答by Rick
If you just want to convert a string to be available for download you can try this using jQuery.
如果您只想将字符串转换为可供下载,您可以使用 jQuery 尝试此操作。
$('a.download').attr('href', 'data:application/csv;charset=utf-8,' + encodeURI(data));
回答by Beau Smith
The package js-file-downloadfrom github.com/kennethjiang/js-file-downloadhandles edge cases for browser support:
来自github.com/kennethjiang/js-file-download的包js-file-download处理浏览器支持的边缘情况:
View sourceto see how it uses techniques mentioned on this page.
查看源代码以了解它如何使用本页提到的技术。
Installation
安装
yarn add js-file-download
npm install --save js-file-download
Usage
用法
import fileDownload from 'js-file-download'
// fileDownload(data, filename, mime)
// mime is optional
fileDownload(data, 'filename.csv', 'text/csv')

