Answers:
您可以使用数据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演示。
适用于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!');
download
属性可以指定文件名;-)
txt
如果您未在文件名中提供扩展名,Chrome只会附加该扩展名。如果这样做,download("data.json", data)
它将按预期工作。
上述所有解决方案均无法在所有浏览器中正常运行。这是在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);
}
}
请注意,根据您的情况,您可能还希望在移除之后调用URL.revokeObjectURLelem
。根据URL.createObjectURL的文档:
每次调用createObjectURL()时,都会创建一个新的对象URL,即使您已经为同一对象创建了一个URL。当您不再需要它们时,必须通过调用URL.revokeObjectURL()释放它们。卸载文档时,浏览器将自动释放这些文件。但是,为了获得最佳性能和内存使用率,如果有安全的时间可以明确卸载它们,则应该这样做。
Failed: network error
了Chrome。这个很好用。
上面的所有示例在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);
a.click()
因为它认为Blob URL是跨域的,所以它在行上抛出“访问被拒绝” 。
我很高兴使用FileSaver.js。它的兼容性非常好(IE10 +和其他所有功能),并且使用非常简单:
var blob = new Blob(["some text"], {
type: "text/plain;charset=utf-8;",
});
saveAs(blob, "thing.txt");
<a>
。
以下方法适用于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,可用于创建和下载文件。
此解决方案直接从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上有效的解决方案:(我需要一个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")
如果您只想转换一个字符串以供下载,则可以使用jQuery进行尝试。
$('a.download').attr('href', 'data:application/csv;charset=utf-8,' + encodeURI(data));
该包的js文件下载从github.com/kennethjiang/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')
如前所述,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()
var element = document.createElement('a');
element.setAttribute('href', 'data:text/text;charset=utf-8,' + encodeURI(data));
element.setAttribute('download', "fileName.txt");
element.click();
我们可以使用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.id = "download"
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:圆形
不支持value参数中的引用(边缘)
使用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()
您甚至可以做一个比URI更好的事情-使用Chrome,您还可以建议文件的名称,如本博客文章中有关使用URI命名下载的说明中所述。
以下方法适用于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');
对我来说,这很完美,下载了相同的文件名和扩展名
<a href={"data:application/octet-stream;charset=utf-16le;base64," + file64 } download={title} >{title}</a>
“ title”是带有扩展名的文件名sample.pdf
,例如waterfall.jpg
,等等。
“ file64”是base64内容,例如: Ww6IDEwNDAsIFNsaWRpbmdTY2FsZUdyb3VwOiAiR3JvdXAgQiIsIE1lZGljYWxWaXNpdEZsYXRGZWU6IDM1LCBEZW50YWxQYXltZW50UGVyY2VudGFnZTogMjUsIFByb2NlZHVyZVBlcmNlbnQ6IDcwLKCFfSB7IkdyYW5kVG90YWwiOjEwNDAsIlNsaWRpbmdTY2FsZUdyb3VwIjoiR3JvdXAgQiIsIk1lZGljYWxWaXNpdEZsYXRGZWUiOjM1LCJEZW50YWxQYXltZW50UGVyY2VudGFnZSI6MjUsIlByb2NlZHVyZVBlcmNlbnQiOjcwLCJDcmVhdGVkX0J5IjoiVGVycnkgTGVlIiwiUGF0aWVudExpc3QiOlt7IlBhdGllbnRO
我会使用<a></a>
标签,然后设置href='path'
。然后,在<a>
元素之间放置一个图像,这样我就可以看到它。如果您愿意,可以创建一个函数来更改href
这样它不仅会是相同的链接,而且是动态的。
如果您想使用javascript访问<a>
标签,请给它一个标签id
。
从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");
}
}