Имя файла BLOB-объекта JavaScript без ссылки
Как установить имя файла BLOB-объекта в JavaScript при принудительной загрузке его через window.location?
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.
13 ответов
Единственный способ, которым я знаю, - это трюк, используемый FileSaver.js:
- Создать скрытый
<a>
тег. - Установите его
href
приписать 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.
- Некоторые форматы файлов считаются браузерами небезопасными, и загрузка не удалась. Сохранение файлов JSON с расширением txt работает для меня.
Я просто хотел бы остановиться на принятом ответе с поддержкой 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();
}
Вот пример Fiddle. Божья скорость
Тот же принцип, что и решения выше. Но у меня были проблемы с Firefox 52.0 (32 бита), когда большие файлы (>40 МБ) усекаются в случайных местах. Перепланирование вызова 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([csv], {type: "text/csv"});
window.navigator.msSaveOrOpenBlob(blob, fileName);
} else {// other browsers
let file = new File([csv], fileName, {type: "text/csv"});
let exportUrl = URL.createObjectURL(file);
window.location.assign(exportUrl);
URL.revokeObjectURL(exportUrl);
}
}
Это мое решение. С моей точки зрения, нельзя обойти<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>
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);
}
}
Рабочий пример кнопки загрузки для сохранения фотографии кошки с адреса как "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 у меня не работал. он загружается нормально, но загружается без расширения для файла CSV на платформе Windows. Следующее сработало для меня.
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);
Вместо этого используйте файл
Имя поддержки файла , более того, оно создается поверх Blob и может использоваться, когда вы хотите получить объект Blob для файла в файловой системе пользователя.
var file = new File([json], name, {type: "octet/stream"});
это хорошее простое решение для этого.
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();
}
При использовании
window.location
не обязательно, вы можете просто использовать
doc.output('save', 'filename.pdf');
чтобы скачать сгенерированный файл.
Если вы хотите загрузить 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');
$http.get(FILE_URL { responseType: 'arraybuffer' }).then(function(response) { var file = new Blob([response.data], {type: fType}); a.href = window.URL.createObjectURL(file); a.download = fname; a.click(); });