Скачать файл данных url

Я играю с идеей создания полностью основанной на javascript утилиты zip/unzip, к которой любой может получить доступ из браузера. Они могут просто перетащить свой почтовый индекс прямо в браузер, и это позволит им загрузить все файлы внутри. Они также могут создавать новые zip-файлы, перетаскивая отдельные файлы в.

Я знаю, что было бы лучше сделать это на стороне сервера, но этот проект просто для развлечения.

Перетаскивание файлов в браузер должно быть достаточно простым, если я воспользуюсь различными доступными методами. (стиль Gmail)

Надеюсь, кодирование / декодирование должно быть в порядке. Я видел несколько z3-библиотек as3, так что я уверен, что со мной все будет в порядке.

Моя проблема заключается в загрузке файлов в конце..

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

это отлично работает в Firefox, но не в Chrome.

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

Кто-нибудь может придумать другое решение или какой-то способ обойти?

16 ответов

Решение

Идеи:

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

  • Используйте downloadify вместо URL-адресов данных (будет работать и для IE)

Если вы также хотите дать предлагаемое имя файлу (вместо "загрузки" по умолчанию), вы можете использовать следующее в 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");

function download(dataurl, filename) {
  var a = document.createElement("a");
  a.href = dataurl;
  a.setAttribute("download", filename);
  var b = document.createEvent("MouseEvents");
  b.initEvent("click", false, true);
  a.dispatchEvent(b);
  return false;
}

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

Хочу поделиться своим опытом и помочь кому-то, кто застрял в загрузках, не работающих в 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);

Вот чистое решение 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.

Существует несколько решений, но они зависят от HTML5 и еще не были полностью реализованы в некоторых браузерах. Примеры ниже были протестированы в Chrome и Firefox (частично работает).

  1. Пример холста с поддержкой сохранения в файл. Просто установите свой document.location.href к URI данных.
  2. Пример загрузки якоря. Оно использует <a href="your-data-uri" download="filename.txt"> указать имя файла.

Это можно полностью решить на 100% с помощью одного лишь HTML. Просто установите href приписывать "data:(mimetypeheader),(url)". Например...

      <a
    href="data:video/mp4,http://www.example.com/video.mp4"
    target="_blank"
    download="video.mp4"
>Download Video</a>

Рабочий пример: JSFiddle Demo .

Поскольку мы используем URL-адрес данных, нам разрешено устанавливать тип mimetype, который указывает тип данных для загрузки. Документация:

URL-адреса данных состоят из четырех частей: префикса (data :), MIME-типа, указывающего тип данных, необязательного токена base64, если он не является текстовым, и самих данных. (Источник: MDN Web Docs: URL-адреса данных.)

Составные части:

  • <a ...> : Тег ссылки.
  • href="data:video/mp4,http://www.example.com/video.mp4" : Здесь мы устанавливаем ссылку на data: с заголовком, предварительно настроенным на video/mp4. За ним следует mimetype заголовка. IE, для .txt файл, это было бы text/plain. И затем запятая отделяет его от ссылки, которую мы хотим скачать.
  • target="_blank" : Это указывает на необходимость открытия новой вкладки, это не важно, но помогает направить браузер к желаемому поведению.
  • download: Это имя файла, который вы загружаете.

Комбинируя ответы от @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');

Если вам действительно нужно только действие загрузки, например, если вы привяжете его к какой-либо кнопке, которая будет генерировать URL-адрес на лету при нажатии (например, в Vue или React), вы можете сделать что-то очень простое:

      const link = document.createElement('a')
link.href = url
link.click()

В моем случае файл уже имеет правильное имя, но вы можете установить его благодаря filename если нужно.

Можно также инициировать загрузку данных URL через JavaScript. См. /questions/41108489/rabotaet-li-execcommand-saveas-v-firefox/41108496#41108496 для такого решения (вместе с примерами текстовых ссылок).

Опоздав на вечеринку, если вы хотите использовать функцию без использования DOM, вот оно, так как DOM может быть даже недоступен по какой-либо причине.

Это должно быть применимо в любом браузере, который имеет API выборки.

Просто проверьте это здесь:

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

Пожалуйста, поддержите здесь ответ Йети: сохраните холст локально в 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");

Ваша проблема сводится к тому, что "не все браузеры будут поддерживать это".

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

Цитирую этот ответ:

Загрузите файл, затем предоставьте его пользователю как base64 (чтобы избежать проблем с CORS)

$.get(/*...*/,function (result)
{
    var blob=new Blob([result]);
    var link=document.createElement('a');
    link.href=window.URL.createObjectURL(blob);
    link.download="myFileName.txt";
    link.click();

});

Это IE 10+, Chrome 8+, FF 4+. См. https://developer.mozilla.org/en-US/docs/Web/API/URL.createObjectURL

Он будет загружать только файлы в Chrome, Firefox и Opera. При этом используется атрибут загрузки тега привязки, чтобы браузер загружал его.

      export const downloadAs = async (url: string, name: string) => {
  const blob = await axios.get(url, {
    headers: {
      'Content-Type': 'application/octet-stream',
    },
    responseType: 'blob',
  });
  const a = document.createElement('a');
  const href = window.URL.createObjectURL(blob.data);
  a.href = href;
  a.download = name;
  a.click();
};

Вы можете использовать решение с чистым кодом, указать свой URL-адрес в константе и установить его как параметр метода open вместо этого в окне объекта.

Другие вопросы по тегам