window.location
强制下载时,如何在JavaScript中设置blob文件的名称?function newFile(data) {
var json = JSON.stringify(data);
var blob = new Blob([json], {type: "octet/stream"});
var url = window.URL.createObjectURL(blob);
window.location.assign(url);
}
运行以上代码即可立即下载文件,而无需刷新页面,如:
bfefe410- 8d9c-4883-86c5-d76c50a24a1d
我想将文件名设置为my-download.json。
#1 楼
我知道的唯一方法是FileSaver.js使用的技巧:创建一个隐藏的
<a>
标记。将其
href
属性设置为Blob的URL。/>将其
download
属性设置为文件名。 单击
<a>
标记。这是一个简化的示例(jsfiddle):
var saveData = (function () {
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
return function (data, fileName) {
var json = JSON.stringify(data),
blob = new Blob([json], {type: "octet/stream"}),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
};
}());
var data = { x: 42, s: "hello, world", d: new Date() },
fileName = "my-download.json";
saveData(data, fileName);
我写这个示例只是为了为了说明这个想法,请在生产代码中使用FileSaver.js代替。
注释
较旧的浏览器不支持“ download”属性,因为该属性是HTML5。
某些文件格式被浏览器视为不安全,下载失败。保存带有txt扩展名的JSON文件对我而言是有效的。
#2 楼
我只是想扩展对Internet Explorer(无论如何都是最新版本)的支持,并使用jQuery整理代码:$(document).ready(function() {
saveFile("Example.txt", "data:attachment/text", "Hello, world.");
});
function saveFile (name, type, data) {
if (data !== null && navigator.msSaveBlob)
return navigator.msSaveBlob(new Blob([data], { type: type }), name);
var a = $("<a style='display: none;'/>");
var url = window.URL.createObjectURL(new Blob([data], {type: type}));
a.attr("href", url);
a.attr("download", name);
$("body").append(a);
a[0].click();
window.URL.revokeObjectURL(url);
a.remove();
}
这里是一个小提琴的例子。 Godspeed。
评论
工作完美。
– N8allan
19年5月25日在3:23
我使用了公认的解决方案,但在Firefox中不起作用!我仍然不知道为什么。您的解决方案在Firefox中有效。谢谢。
– elahehab
19-09-30在7:57
#3 楼
与上述解决方案相同的原理。但是我遇到了Firefox 52.0(32位)的问题,其中大文件(> 40 MBytes)在任意位置被截断。重新安排revokeObjectUrl()的调用可以解决此问题。function saveFile(blob, filename) {
if (window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, filename);
} else {
const a = document.createElement('a');
document.body.appendChild(a);
const url = window.URL.createObjectURL(blob);
a.href = url;
a.download = filename;
a.click();
setTimeout(() => {
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
}, 0)
}
}
jsfiddle示例
评论
我发现此setTimeout()hack修复了MS Edge,该文件根本无法下载。但是,只有对revokeObjectURL()的调用需要延迟。
–罗素·菲利普斯(Russell Phillips)
18/12/17在0:56
我发现“ if(window.navigator.msSaveOrOpenBlob)”是我的诀窍
–雅克·奥利维尔(Jacques Olivier)
19年1月29日在14:10
#4 楼
很晚了,但是由于我遇到了同样的问题,所以我添加了解决方案:function newFile(data, fileName) {
var json = JSON.stringify(data);
//IE11 support
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
let blob = new Blob([json], {type: "application/json"});
window.navigator.msSaveOrOpenBlob(blob, fileName);
} else {// other browsers
let file = new File([json], fileName, {type: "application/json"});
let exportUrl = URL.createObjectURL(file);
window.location.assign(exportUrl);
URL.revokeObjectURL(exportUrl);
}
}
评论
谢谢@ben。一切正常。没有dom元素,没有像click事件那样触发。只要适当扩展,它就很棒。但是不考虑给定的文件名,而是下载“
–Ram Babu S
19年1月23日在4:19
在location.assign之后调用revokeObjectURL在Firefox中可以正常工作,但是会中断Chrome的下载。
–弗雷德
19年1月25日15:49
请注意,“ Edge不支持File构造函数。”参考caniuse.com/#feat=fileapi
–user1477388
19-09-23在18:39
这应该是正确的答案。在DOM树中创建无用的对象毫无意义
–路易斯·费利佩(Luiz Felipe)
2月17日19:25
就像@RamBabuS所说的,这不保留fileName,但除此之外,它对我来说非常合适
– Manu
3月5日下午16:41
#5 楼
saveFileOnUserDevice = function(file){ // content: blob, name: string
if(navigator.msSaveBlob){ // For ie and Edge
return navigator.msSaveBlob(file.content, file.name);
}
else{
let link = document.createElement('a');
link.href = window.URL.createObjectURL(file.content);
link.download = file.name;
document.body.appendChild(link);
link.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true, view: window}));
link.remove();
window.URL.revokeObjectURL(link.href);
}
}
评论
有什么办法可以在新窗口中打开?
– Enrique Altuna
19年1月18日在21:59
我认为您可以调用link.click()而不是调度鼠标事件。
–弗雷德
19年1月25日在15:50
#6 楼
下载按钮的工作示例,用于将URL中的猫照片另存为“ cat.jpg”:HTML:
<button onclick="downloadUrl('https://i.imgur.com/AD3MbBi.jpg', 'cat.jpg')">Download</button>
JavaScript :
function downloadUrl(url, filename) {
let xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "blob";
xhr.onload = function(e) {
if (this.status == 200) {
const blob = this.response;
const a = document.createElement("a");
document.body.appendChild(a);
const blobUrl = window.URL.createObjectURL(blob);
a.href = blobUrl;
a.download = filename;
a.click();
setTimeout(() => {
window.URL.revokeObjectURL(blobUrl);
document.body.removeChild(a);
}, 0);
}
};
xhr.send();
}
#7 楼
window.location.assign对我不起作用。它可以很好地下载,但是在Windows平台上下载时没有CSV文件扩展名。以下对我有用。 var blob = new Blob([csvString], { type: 'text/csv' });
//window.location.assign(window.URL.createObjectURL(blob));
var link = window.document.createElement('a');
link.href = window.URL.createObjectURL(blob);
// Construct filename dynamically and set to link.download
link.download = link.href.split('/').pop() + '.' + extension;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
#8 楼
这是我的解决方案。从我的角度来看,您不能绕过<a>
。 function export2json() {
const data = {
a: '111',
b: '222',
c: '333'
};
const a = document.createElement("a");
a.href = URL.createObjectURL(
new Blob([JSON.stringify(data, null, 2)], {
type: "application/json"
})
);
a.setAttribute("download", "data.json");
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
<button onclick="export2json()">Export data to json file</button>
评论
@AshBlue“下载”属性需要HTML5。我的代码只是一个示例,您也可以尝试FileSaver.js演示页面:eligrey.com/demos/FileSaver.js
– kol
13-10-13在8:57
有趣的是,如果您反复尝试以这种方式下载txt(一次又一次按下jsfiddle.net上的Run按钮),则下载有时会失败。
– kol
13-10-15在9:13
只是想提一下,此解决方案不适用于文件大小大于特定阈值的文件。例如-> 2 MB用于Chrome。此大小因浏览器而异。
– manojadams
17年9月2日在15:58
这对我不起作用,因为我需要在新选项卡中打开文件。我必须在Chrome中显示PDF,但是我需要在URL工具栏中显示用户友好名称,如果用户要通过下载图标进行下载,则必须在文件中放入相同的用户友好名称。
–AdriánParedes
17年12月11日下午14:42
只需添加一下,您就无需真正将标签安装到主体上即可正常工作(刚才在Chrome中尝试过)
–超越代码
19年8月12日在10:37