当通过 window.location
强制下载 blob 文件时,如何在 JavaScript 中设置它的名称?
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 。
我知道的唯一方法是 FileSaver.js 使用的技巧:
创建一个隐藏的 标签。将其 href 属性设置为 blob 的 URL。将其下载属性设置为文件名。单击 标记。
这是一个简化的示例 (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 代替。
笔记
较旧的浏览器不支持“下载”属性,因为它是 HTML5 的一部分。
浏览器认为某些文件格式不安全,下载失败。保存带有 txt 扩展名的 JSON 文件对我有用。
我只是想通过支持 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();
}
Here is an example Fiddle。 神速。
与上述解决方案的原理相同。但是我遇到了 Firefox 52.0(32 位)的问题,其中大文件(> 40 MB)在随机位置被截断。重新安排 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)
}
}
迟到了,但由于我遇到了同样的问题,我添加了我的解决方案:
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);
}
}
location.assign
之后调用 revokeObjectURL
在 Firefox 中可以正常工作,但会中断 Chrome 上的下载。
fileName
,但除此之外对我来说非常有用
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);
}
}
link.click()
而不是调度鼠标事件。
这是我的解决方案。从我的角度来看,您无法绕过<a>
。
函数 export2json() { 常量数据 = { 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("下载", "data.json"); document.body.appendChild(a); a.点击(); document.body.removeChild(a); }
下载按钮的工作示例,将来自 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();
}
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);
这是一个很好的简单解决方案。
function downloadBloob(blob,FileName) {
var link = document.createElement("a"); // Or maybe get it from the current document
link.href = blob;
link.download = FileName;
link.click();
}
如果您想下载 pdf 并且不强制使用 window.location
,则可以使用 jsPdf,如下所示:
// Create document
const doc = new jsPDF('l', 'px', 'a4');
// [...] Add here the jsPdf doc filling
// Launch the document downloading
doc.output('save', 'filename.pdf');