开发者问题收集

如何在内存中创建一个文件供用户下载,但不通过服务器?

2010-09-08
676761

有没有办法在客户端创建一个文本文件并提示用户下载它,而无需与服务器进行任何交互?

我知道我无法直接写入他们的机器(安全性和所有),但我可以创建文件并提示他们保存它吗?

3个回答

适用于 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>

用法

download('test.txt', 'Hello world!');
Matěj Pokorný
2013-08-12

您可以使用数据 URI。浏览器支持各不相同;请参阅 维基百科 。示例:

<a href="data:application/octet-stream;charset=utf-16le;base64,//5mAG8AbwAgAGIAYQByAAoA">text file</a>

八位字节流用于强制下载提示。否则,它可能会在浏览器中打开。

对于 CSV,您可以使用:

<a href="data:application/octet-stream,field1%2Cfield2%0Afoo%2Cbar%0Agoo%2Cgai%0A">CSV Octet</a>

尝试 jsFiddle 演示

Matthew Flaschen
2010-09-08

IE 10+、Firefox 和 Chrome 的示例( 不带 jQuery 或任何其他库):

function save(filename, data) {
    const blob = new Blob([data], {type: 'text/csv'});
    if(window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveBlob(blob, filename);
    }
    else{
        const 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 的文档:

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.

Ludovic Feltz
2015-11-05