Завантажте файл URL-адреси даних


127

Я граю з ідеєю зробити повністю zip / unzip утиліту на основі JavaScript, до якої кожен може отримати доступ із браузера. Вони можуть просто перетягнути свій поштовий індекс безпосередньо у браузер, і це дозволить завантажити всі файли всередині. Вони також можуть створювати нові поштові файли, перетягуючи в них окремі файли.

Я знаю, що краще було б це зробити на сервер, але цей проект просто для задоволення.

Перетягування файлів у браузер має бути досить простим, якщо я скористаюся різними доступними методами. (Стиль Gmail)

Сподіваємось, кодування / розшифрування повинні бути нормальними. Я бачив кілька бібліотек z3 з zip, тож я впевнений, що мені слід добре.

Моя проблема - завантаження файлів наприкінці.

window.location = 'data:jpg/image;base64,/9j/4AAQSkZJR....' 

це чудово працює у firefox, але не в хромі.

Я можу вставляти файли у вигляді зображень із простою хромою за допомогою хрома <img src="data:jpg/image;ba.." />, але ці файли не обов'язково будуть зображеннями. Вони можуть бути будь-якого формату.

Хтось може придумати інше рішення чи якесь вирішення?


Поточна підтримка , на жаль, досить обмежена
Casebash

Відповіді:


42

Ідеї:

  • Спробуйте <a href="data:...." target="_blank">(Не перевірено)

  • Використовуйте завантажувати замість URL-адрес даних (буде працювати і для IE)


@jcubic дякую за вказівку на мертве посилання. Здається, новим місцем завантаження є github.com/dcneiner/Downloadify
Pekka

Якщо ви не можете використовувати Flash, але у вас працює компонент на сервері Java, ви можете скористатися цим: github.com/suprememoocow/databounce . Він використовує сервлет для "відмов" даних від клієнта. Виконати такий самий трюк було б досить легко в інших технологіях на стороні сервера, таких як Python, ASP.NET тощо
Andrew Newdigate

Чи є спосіб це зробити без спалаху? URL-адреса даних для всіх браузерів, окрім IE та якогось ActiveX-Foo для IE? (Таким чином мені вдалося відтворювати музику без спалаху: аудіо HTML5 для всіх браузерів, окрім IE та ActiveX для IE.)
panzi

Downloadify очікує флеш-плеєр у браузері. Якщо у користувача немає флеш-програвача, файл не завантажується
Jeevanandan J

186

Якщо ви також хочете дати запропонованому імені файлу (замість "завантаження" за замовчуванням), ви можете використовувати наступні версії в Chrome, Firefox та деяких версіях IE:

function downloadURI(uri, name) {
  var link = document.createElement("a");
  link.download = name;
  link.href = uri;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  delete link;
}

І наступний приклад показує, що це використання:

downloadURI("data:text/html,HelloWorld!", "helloWorld.txt");

6
Ви можете спростити це link.click()замість своєї eventFire-функції ... jsfiddle.net/ARTsinn/Ezx5m
yckart

3
Приємне рішення. але чим після цього стає посилання?
webshaker

6
Змінна 'посилання' виходить із сфери застосування в кінці функції (зауважте, ми ніколи не додавали її до dom), тому сміття буде зібране незабаром після.
Owencm

8
Це працює лише в Chrome. Якщо ви хочете, щоб він працював у Firefox / IE, подивіться на відповідь від @MartinoDino.
TrueWill

1
Я спробував з download.js , як тут пропонується, і, здається, працює. :)
joaorodr84

56

function download(dataurl, filename) {
  var a = document.createElement("a");
  a.href = dataurl;
  a.setAttribute("download", filename);
  a.click();
}

download("data:text/html,HelloWorld!", "helloWorld.txt");

або:

function download(url, filename) {
fetch(url).then(function(t) {
    return t.blob().then((b)=>{
        var a = document.createElement("a");
        a.href = URL.createObjectURL(b);
        a.setAttribute("download", filename);
        a.click();
    }
    );
});
}

download("https://get.geojs.io/v1/ip/geo.json","geoip.json")
download("data:text/html,HelloWorld!", "helloWorld.txt");


натисніть подію на неіснуючий елемент: D немає потреби в додатку.
Зібрі

1
так. ви можете просто зателефонувати a.click () після створення елемента 'a', а потім встановити href a.
user1709076

у минулому виклик a.click () безпосередньо не працював би, але він працює з подією. Зараз вони обоє працюють.
Зібрі

1
Це працює в більшості сучасних браузерів, але я зазначу, що додавання до документа та видалення його необхідно для підтримки деяких старих браузерів.
Owencm

3
Ваше друге рішення слід використовувати, коли даніUri стають занадто великими (залежить від браузера, але Chrome не сприймає Uri декількох мегабайт на моєму досвіді). Дивіться також stackoverflow.com/questions/38781968/… .
neural5torm

27

Хочете поділитися своїм досвідом та допомогти комусь, хто затримався над завантаженнями, які не працюють у Firefox та оновленою відповіддю до 2014 р. Фрагмент нижче буде працювати як у Firefox, так і в chrome, і він прийме ім'я файлу:

  // Construct the <a> element
  var link = document.createElement("a");
  link.download = thefilename;
  // Construct the uri
  var uri = 'data:text/csv;charset=utf-8;base64,' + someb64data
  link.href = uri;
  document.body.appendChild(link);
  link.click();
  // Cleanup the DOM
  document.body.removeChild(link);

4
На жаль, це не працює в Safari. Сафарі, схоже, не розпізнає downloadатрибут. Спасибі все одно, це настільки близько, як я можу отримати на даний момент.
Моріц Петерсен

це призводить до перенаправлення вікна на значення href для мене в IE 11. prevetDefault (); не зупиняє поведінку в IE
b_dubb

1
Дякую, також якщо btoaце не визначено (наприклад, у вузлі проекту, що порушив фронт) const btxt = new Buffer(text).toString('base64'); const uri = 'data:text/csv;charset=utf-8;base64,' + btxt + ';'
Іван Борщов

2
видалення посилання є безглуздим, воно виходить за межі наступного рядка і буде зібрано сміття, це не дійсна ціль для видалення.
macdja38

1
немає необхідності в document.body.appendChild ... не бачать мою відповідь stackoverflow.com/a/45905238/236062
Zibri

13

Ось чисте рішення JavaScript, яке я перевірив, працюючи в Firefox та Chrome, але не в Internet Explorer:

function downloadDataUrlFromJavascript(filename, dataUrl) {

    // Construct the 'a' element
    var link = document.createElement("a");
    link.download = filename;
    link.target = "_blank";

    // Construct the URI
    link.href = dataUrl;
    document.body.appendChild(link);
    link.click();

    // Cleanup the DOM
    document.body.removeChild(link);
    delete link;
}

Досі знайдені крос-браузерні рішення:

downloadify -> Потрібен Flash

databounce -> Тестовано в IE 10 і 11, і не працює для мене. Потрібен сервлет і певна налаштування. (Неправильно виявляє навігатор. Мені довелося встановити IE в режимі сумісності для тестування, схему за замовчуванням у сервлеті, параметри JavaScript об'єкта з правильним шляхом сервлетів для абсолютних шляхів ...) Для браузерів, які не є IE, він відкриває файл у тому ж вікні.

download.js -> http://danml.com/download.html Ще одна схожа бібліотека, але не перевірена. Стверджує, що це чистий JavaScript, не вимагає сервлета чи Flash, але не працює в IE <= 9.


download.js досить добре. Просто зробив швидку перевірку на IE11, він працює. Дуже дякую!
Рікі Цзяо

12

Є кілька рішень, але вони залежать від HTML5 і ще не були повністю реалізовані в деяких браузерах. Приклади нижче були протестовані в Chrome і Firefox (частково працює).

  1. Приклад полотна з підтримкою збереження у файлі. Просто встановіть свій document.location.hrefURI даних.
  2. Приклад завантаження якоря . Він використовується <a href="your-data-uri" download="filename.txt">для визначення імені файлу.

3
приклад полотна веде до 404
Карел Білек

Атрибут завантаження працює для мене для URL-адреси даних у форматі pdf у хромованому та мобільному сафарі.
bbsimonbb

7

Поєднуючи відповіді від @owencm та @ Chazt3n, ця функція дозволить завантажувати текст із IE11, Firefox та Chrome. (Вибачте, у мене немає доступу до Safari чи Opera, але, будь ласка, додайте коментар, якщо ви спробуєте, і це спрацює.)

initiate_user_download = function(file_name, mime_type, text) {
    // Anything but IE works here
    if (undefined === window.navigator.msSaveOrOpenBlob) {
        var e = document.createElement('a');
        var href = 'data:' + mime_type + ';charset=utf-8,' + encodeURIComponent(text);
        e.setAttribute('href', href);
        e.setAttribute('download', file_name);
        document.body.appendChild(e);
        e.click();
        document.body.removeChild(e);
    }
    // IE-specific code
    else {
        var charCodeArr = new Array(text.length);
        for (var i = 0; i < text.length; ++i) {
            var charCode = text.charCodeAt(i);
            charCodeArr[i] = charCode;
        }
        var blob = new Blob([new Uint8Array(charCodeArr)], {type: mime_type});
        window.navigator.msSaveOrOpenBlob(blob, file_name);
    }
}

// Example:
initiate_user_download('data.csv', 'text/csv', 'Sample,Data,Here\n1,2,3\n');

1

Для тих, хто має проблеми в IE:

Будь ласка, підкріпіть тут відповідь Yetti: збереження полотна локально в IE

dataURItoBlob = function(dataURI) {
    var binary = atob(dataURI.split(',')[1]);
    var array = [];
    for(var i = 0; i < binary.length; i++) {
        array.push(binary.charCodeAt(i));
    }
    return new Blob([new Uint8Array(array)], {type: 'image/png'});
}

var blob = dataURItoBlob(uri);
window.navigator.msSaveOrOpenBlob(blob, "my-image.png");

0

По суті, ваша проблема зводиться до того, що "не всі браузери підтримуватимуть це".

Ви можете спробувати вирішити і обслуговувати розпаковані файли з об’єкта Flash, але тоді ви втратите чистоту лише JS (все одно, я не впевнений, чи можете ви в даний час "перетягувати файли у браузер" без якогось вирішення Flash. - це можливо функція HTML5?)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.