协慌网

登录 贡献 社区

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

有什么方法可以在客户端上创建文本文件并提示用户下载文本文件,而无需与服务器进行任何交互?我知道我不能直接写给他们的机器(安全性和全部),但是我可以创建并提示他们保存吗?

答案

适用于 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!');

您可以使用数据 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 演示

上述所有解决方案均无法在所有浏览器中正常运行。这是最终在 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()时,都会创建一个新的对象 URL,即使您已经为同一对象创建了一个 URL。当不再需要它们时,必须通过调用 URL.revokeObjectURL()释放它们。当文档被卸载时,浏览器将自动释放这些文件。但是,为了获得最佳性能和内存使用率,如果可以安全地显式卸载它们,则应该这样做。