我知道我不能直接写到他们的机器上(安全性和全部),但是我可以创建并提示他们保存吗?
#1 楼
您可以使用数据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限制了对数据uri的支持。 IE 8将大小限制为32KB,而IE 7和更低版本完全不支持。
–达琳·迪米特洛夫(Darin Dimitrov)
2010-09-08 6:32
在Chrome版本19.0.1084.46中,此方法生成以下警告:“资源被解释为文档,但以MIME类型text / csv传输:“ data:text / csv,field1%2Cfield2%0Afoo%2Cbar%0Agoo%2Cgai%0A”。 ”未触发下载
–克里斯
2012年5月16日11:44
它现在确实可以在Chrome中运行(已针对v20和v21进行了测试),但不适用于IE9(可能只是jsFiddle,但我对此表示怀疑)。
–earcam
2012年8月30日在16:20
正确的字符集几乎可以肯定是UTF-16,除非您有将其转换为UTF-8的代码。 JavaScript在内部使用UTF-16。如果有文本或CSV文件,则以'\ ufeff'(UTF-16BE的字节顺序标记)开头的字符串,文本编辑器将能够正确读取非ASCII字符。
– Larspars
2014年11月19日在9:06
只需添加download =“ txt.csv”属性即可获得正确的文件名和扩展名,并告诉您的操作系统该怎么做。
–elshnkhll
16年1月15日在16:33
#2 楼
适用于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!');
评论
是的这正是@MatthewFlaschen大约3年前在这里发布的内容。
–约瑟夫·西尔伯(Joseph Silber)
13年8月12日在22:01
是的,但是具有下载属性,您可以指定文件名;-)
–MatějPokorný
13年8月12日在22:08
正如@earcam在上面的评论中已经指出的那样。
–约瑟夫·西尔伯(Joseph Silber)
13年8月13日在0:30
如果您没有在文件名中提供扩展名,Chrome只会附加txt扩展名。如果您下载(“ data.json”,data),它将按预期工作。
–卡尔·史密斯
14年7月19日在14:34
这在Chrome(73.0.3683.86)和Firefox(66.0.2)中对我有用。在IE11(11.379.17763.0)和Edge(44.17763.1.0)中不起作用。
–山姆
19年3月29日在8:40
#3 楼
上述所有解决方案均无法在所有浏览器中正常运行。这是最终在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()释放它们。卸载文档时,浏览器将自动释放这些文件;但是,为了获得最佳性能和内存使用,如果有安全的时间可以明确卸载它们,则应该这样做。评论
太感谢了。我已经尝试了此处列出的所有示例,并且只有此示例适用于任何浏览器。这应该是公认的答案。
– LEM
16年5月27日在16:51
对于AngularJS 1.x应用程序,您可以在创建它们时构建一组Urls,然后在组件的$ onDestroy函数中对其进行清理。这对我来说很棒。
– Splaktar
16年9月6日在18:12
其他答案导致失败:Chrome中的网络错误。这个很好用。
–瞻博网络-
17/09/27在19:25
这对我来说适用于Chrome(73.0.3683.86),Firefox(66.0.2),IE11(11.379.17763.0)和Edge(44.17763.1.0)。
–山姆
19年3月29日在8:41
对于那些希望避免在URL上进行垃圾回收或其他奇怪行为的人,只需这样声明您的blob:const url = URL.createObjectURL(blob,{oneTimeOnly:true})。您随时可以保存该Blob,并在以后需要时生成新的网址。
–丹尼尔(Daniel)
5月1日21:10
#4 楼
上面的所有示例在chrome和IE上都可以正常运行,但在Firefox中无法运行。请务必考虑将锚点附加到主体上,并在单击后将其删除。
评论
但是:IE 10中有一个打开的错误(我仍然在11中看到过),在a.click()行上抛出“访问被拒绝”,因为它认为Blob URL是跨域的。
–马特
2014-12-16 19:44
@Matt数据uri在某些浏览器中是跨源的。据我所知,不仅是msie,还有chrome。您可以通过尝试向JavaScript注入数据uri来对其进行测试。它将无法访问网站的其他部分...
– inf3rno
2015年9月13日在0:13
“以上所有示例在chrome和IE中都可以正常运行,但在Firefox中无法运行。”由于答案的顺序会随时间变化,因此您撰写本文时,尚不清楚哪个答案在您的答案之上。您能确切指出哪些方法在Firefox中不起作用吗?
–凯文
18年4月2日在18:57
b这种Blob方法对于非常大的文件效果更好。
– joe
7月29日13:05
#5 楼
我很高兴使用FileSaver.js。它的兼容性非常好(IE10 +和其他所有功能),并且使用非常简单:var blob = new Blob(["some text"], {
type: "text/plain;charset=utf-8;",
});
saveAs(blob, "thing.txt");
评论
这在Chrome上效果很好。如何允许用户指定磁盘上文件的位置?
– gregm
13年5月22日在18:40
哇,感谢您易于使用的库。这很容易是最好的答案,如今,谁在乎使用HTML <5的人呢?
–notbad.jpeg
13年6月19日在21:16
@gregm我不确定您可以使用此插件。
–丹尼尔·巴克马斯特(Daniel Buckmaster)
2013年6月20日下午6:23
@gregm:您的意思是下载位置?这与FileSaver.js无关,您需要设置浏览器配置,以便它在每次下载前都要求一个文件夹,或者使用上的新下载属性。
– CodeManX
2014年12月3日15:54
这是IE 10+系列浏览器的绝佳解决方案。 IE尚不支持下载HTML 5标记,并且此页面上的其他解决方案(以及其他讨论相同问题的SO页面)对我来说根本不起作用。 FileSaver ftw!
–TMc
2015年1月12日在20:32
#6 楼
以下方法适用于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>
请参阅以下操作:http://jsfiddle.net/Kg7eA/
Firefox和Chrome支持数据URI进行导航,这使我们可以通过导航到数据URI来创建文件,而IE出于安全目的不支持它。
另一方面,IE具有用于保存Blob的API,可用于创建和下载文件。
评论
我只是使用jquery附加事件(onclick和onready)并设置属性,您也可以使用普通JS来完成。核心部分(window.navigator.msSaveOrOpenBlob)不需要jquery。
–dinesh ygv
16年6月6日在2:17
数据uri方法仍然存在大小限制,不是吗?
– phil
17年6月26日在8:21
msSaveOrOpenBlob在这里显示为已过时:developer.mozilla.org/zh-CN/docs/Web/API/Navigator/msSaveBlob
–扁平
5月14日0:30
#7 楼
该解决方案直接从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存储库:
下载保护程序模块
评论
它在Chrome上可以很好地工作,但在Firefox上却不能。它确实制作并下载了文件,但该文件为空。无内容。有什么想法吗?尚未在IE上进行测试...
– Narx
17年2月16日在16:26
除了函数没有名字外,这是我的最爱
–约拉科·冈萨雷斯(Yoraco Gonzales)
18年8月20日在20:32
#8 楼
来自github.com/kennethjiang/js-file-download的js-file-download软件包可处理浏览器支持的一些极端情况:查看源代码以了解其如何使用本页中提到的技术。 >
安装
yarn add js-file-download
npm install --save js-file-download
用法
import fileDownload from 'js-file-download'
// fileDownload(data, filename, mime)
// mime is optional
fileDownload(data, 'filename.csv', 'text/csv')
评论
谢谢-刚刚经过测试-适用于Windows上的Firefox,Chrome和Edge
–布莱恩·伯恩斯(Brian Burns)
19年4月13日在22:07
#9 楼
在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")
评论
Ludovic的答案包括这么大,以及对其他浏览器的支持。
– Dan Dascalescu
16年11月5日在21:10
#10 楼
如果您只想转换一个字符串以供下载,则可以使用jQuery进行尝试。$('a.download').attr('href', 'data:application/csv;charset=utf-8,' + encodeURI(data));
评论
如我在此处建议的那样,可能需要先使用带有encodeURI的Scape数据,然后才能评论:stackoverflow.com/a/32441536/4928558
– atfornes
16年6月15日在12:31
#11 楼
我们可以使用URL api,尤其是URL.createObjectURL()和Blob api来编码和下载几乎所有内容。如果下载量很小,则可以正常工作:
document.body.innerHTML +=
`<a id="download" download="PATTERN.json" href="${URL.createObjectURL(new Blob([JSON.stringify("HELLO WORLD", null, 2)]))}"> Click me</a>`
download.click()
download.outerHTML = ""
如果下载量很大,则可以使用下载参数来创建链接元素并触发点击,这是一种更好的方法,而不是使用DOM。
注意链接元素没有附加到文档中,但是单击仍然有效!这样就可以创建数百个Mo的下载。
const stack = {
some: "stuffs",
alot: "of them!"
}
BUTTONDOWNLOAD.onclick = (function(){
let j = document.createElement("a")
j.download = "stack_"+Date.now()+".json"
j.href = URL.createObjectURL(new Blob([JSON.stringify(stack, null, 2)]))
j.click()
})
<button id="BUTTONDOWNLOAD">DOWNLOAD!</button>
奖金!下载任何循环对象,避免出现以下错误:
TypeError:循环对象值(Firefox)TypeError:将循环结构转换为JSON(Chrome和Opera)TypeError:Circular
引用不支持value参数(Edge)
使用https://github.com/douglascrockford/JSON-js/blob/master/cycle.js
在此示例中,将
document
对象下载为json。 /* JSON.decycle */
if(typeof JSON.decycle!=="function"){JSON.decycle=function decycle(object,replacer){"use strict";var objects=new WeakMap();return(function derez(value,path){var old_path;var nu;if(replacer!==undefined){value=replacer(value)}
if(typeof value==="object"&&value!==null&&!(value instanceof Boolean)&&!(value instanceof Date)&&!(value instanceof Number)&&!(value instanceof RegExp)&&!(value instanceof String)){old_path=objects.get(value);if(old_path!==undefined){return{$ref:old_path}}
objects.set(value,path);if(Array.isArray(value)){nu=[];value.forEach(function(element,i){nu[i]=derez(element,path+"["+i+"]")})}else{nu={};Object.keys(value).forEach(function(name){nu[name]=derez(value[name],path+"["+JSON.stringify(name)+"]")})}
return nu}
return value}(object,"$"))}}
document.body.innerHTML +=
`<a id="download" download="PATTERN.json" href="${URL.createObjectURL(new Blob([JSON.stringify(JSON.decycle(document), null, 2)]))}"></a>`
download.click()
#12 楼
如前所述,filesaver是一个很好的软件包,可以在客户端使用文件。但是,对于大文件来说效果不佳。 StreamSaver.js是可以处理大型文件的替代解决方案(在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()
评论
文字编码器目前处于高度实验性状态,建议您避免使用(或填充)它。
–布兰登·布兰查德
17年9月22日在20:07
#13 楼
var element = document.createElement('a');
element.setAttribute('href', 'data:text/text;charset=utf-8,' + encodeURI(data));
element.setAttribute('download', "fileName.txt");
element.click();
评论
这种方法与创建Blob有什么区别?
– Dan Dascalescu
16年11月5日在21:08
#14 楼
截至2014年4月,W3C中可能尚未对FileSytem API进行标准化。我想任何使用blob解决方案的人都应该谨慎使用线程。HTML5引起人们的注意
FileSytem API上的W3C邮件列表
#15 楼
基于@Rick的答案,这确实很有帮助。如果要以这种方式共享它,则必须转义字符串
data
:$('a.download').attr('href', 'data:application/csv;charset=utf-8,'+ encodeURI(data));
`
抱歉,由于我目前在StackOverflow中的声誉较低,我无法对@Rick的答案发表评论。
共享并拒绝了一个编辑建议。
评论
我不能接受这个建议。奇怪...我更新了代码。
–里克
16年6月15日在21:22
#16 楼
此以下功能有效。 private createDownloadableCsvFile(fileName, content) {
let link = document.createElement("a");
link.download = fileName;
link.href = `data:application/octet-stream,${content}`;
return link;
}
评论
您可以在一个新的标签页中打开文件并保留文件名,但不能下载,而只是在一个标签页中打开?
–卡尔·克鲁格·伊尔(Carl Kroeger Ihl)
19/12/5在23:48
#17 楼
以下方法适用于IE10 +,Edge,Opera,FF和Chrome:const saveDownloadedData = (fileName, data) => {
if(~navigator.userAgent.indexOf('MSIE') || ~navigator.appVersion.indexOf('Trident/')) { /* IE9-11 */
const blob = new Blob([data], { type: 'text/csv;charset=utf-8;' });
navigator.msSaveBlob(blob, fileName);
} else {
const link = document.createElement('a')
link.setAttribute('target', '_blank');
if(Blob !== undefined) {
const blob = new Blob([data], { type: 'text/plain' });
link.setAttribute('href', URL.createObjectURL(blob));
} else {
link.setAttribute('href', 'data:text/plain,' + encodeURIComponent(data));
}
~window.navigator.userAgent.indexOf('Edge')
&& (fileName = fileName.replace(/[&\/\#,+$~%.'':*?<>{}]/g, '_')); /* Edge */
link.setAttribute('download', fileName);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
因此,只需调用函数:
saveDownloadedData('test.txt', 'Lorem ipsum');
#18 楼
对我来说,这很完美,可以下载相同的文件名和扩展名<a href={"data:application/octet-stream;charset=utf-16le;base64," + file64 } download={title} >{title}</a>
'title'是具有扩展名的文件名,即
sample.pdf
,waterfall.jpg
等。 br /> 'file64'是base64内容,例如
Ww6IDEwNDAsIFNsaWRpbmdTY2FsZUdyb3VwOiAiR3JvdXAgQiIsIE1lZGljYWxWaXNpdEZsYXRGZWU6IDM1LCBEZW50YWxQYXltZW50UGVyY2VudGFnZTogMjUsIFByb2NlZHVyZVBlcmNlbnQ6IDcwLKCFfSB7IkdyYW5kVG90YWwiOjEwNDAsIlNsaWRpbmdTY2FsZUdyb3VwIjoiR3JvdXAgQiIsIk1lZGljYWxWaXNpdEZsYXRGZWUiOjM1LCJEZW50YWxQYXltZW50UGVyY2VudGFnZSI6MjUsIlByb2NlZHVyZVBlcmNlbnQiOjcwLCJDcmVhdGVkX0J5IjoiVGVycnkgTGVlIiwiUGF0aWVudExpc3QiOlt7IlBhdGllbnRO
#19 楼
我将使用<a></a>
标签,然后设置href='path'
。然后,在<a>
元素之间放置一个图像,以便可以看到它。如果需要,您可以创建一个函数来更改href
,以便它不仅是相同的链接,而且是动态的。也给
<a>
标签添加一个id
使用javascript进行访问。从HTML版本开始:
<a href="mp3/tupac_shakur-how-do-you-want-it.mp3" download id="mp3Anchor">
<img src="some image that you want" alt="some description" width="100px" height="100px" />
</a>
现在使用JavaScript:
*Create a small json file*;
const array = [
"mp3/tupac_shakur-how-do-you-want-it.mp3",
"mp3/spice_one-born-to-die.mp3",
"mp3/captain_planet_theme_song.mp3",
"mp3/tenchu-intro.mp3",
"mp3/resident_evil_nemesis-intro-theme.mp3"
];
//load this function on window
window.addEventListener("load", downloadList);
//now create a function that will change the content of the href with every click
function downloadList() {
var changeHref=document.getElementById("mp3Anchor");
var j = -1;
changeHref.addEventListener("click", ()=> {
if(j < array.length-1) {
j +=1;
changeHref.href=""+array[j];
}
else {
alert("No more content to download");
}
}
#20 楼
这对我有用(Chrome 86): function download(content, mimeType, filename){
var a = document.createElement('a')
var blob = new Blob([content], {type: mimeType})
var url = URL.createObjectURL(blob)
a.setAttribute('href', url)
a.setAttribute('download', filename)
a.click()
}
在这里您可以看到小提琴:
https://jsfiddle.net/Stelios2020/ukmf5304/6/
#21 楼
如果文件包含文本数据,我使用的一种技术是将文本放入textarea元素中,并让用户选择它(在textarea中单击,然后按ctrl-A),然后复制,然后粘贴到文本编辑器中。评论
我曾经考虑过,但是从用户友好的角度来看,这是灾难性的。另外,该文件必须以CSV扩展名保存。尝试告诉您的用户。
–约瑟夫·西尔伯(Joseph Silber)
2010-09-08 7:07
评论
另请参阅:JavaScript:创建和保存文件