Преобразование ZIP в Blob - PullRequest
       17

Преобразование ZIP в Blob

1 голос
/ 03 марта 2020

В нашем приложении Ruby on Rails есть действие контроллера, которое отправляет ZIP:

send_data File.read(zip_pathname), filename: zip_filename, type: 'application/zip'

. Мы делаем это загружаемым, используя атрибут загрузки по ссылке, например:

<%= link_to zip_download_path(@object), download: zip_filename do %>
  <i class="fas fa-download fa-fw"></i> Download ZIP
<% end %>

Работает нормально, но может занять до 5-6 секунд, прежде чем что-либо произойдет (из-за размера ZIP)

Чтобы пользователь не нажимал ссылку снова и показывал, что что-то происходит, мы пытались загрузить загрузку, используя AJAX, а затем превратить ее в BLOB-объект и использовать FileReader для ее загрузки:

const reader = new FileReader();
reader.onload = function(e) {
    const anchor = document.createElement('a');
    anchor.style.display = 'none';
    anchor.href = e.target.result;
    anchor.download = 'download';
    anchor.click();
    hideLoading();
}

$('[download]').on('click', function (e) {
    e.preventDefault();
    showLoading();
    var download = $(this);
    $.get(download.attr('href'), function (data) {
        const blob = new Blob([data], { name: download.attr('download'), type: 'application/zip' });
        reader.readAsDataURL(blob);
    });
});

Это успешно показывает экран загрузки, а затем загружает ZIP и снова скрывает экран загрузки, за исключением что ZIP возвращается как ошибка загрузки, а не как настоящий ZIP, как раньше ... может показаться, что преобразование ZIP в BLOB-объект происходит там, где происходит сбой ...

Возможно ли преобразовать ZIP в Blob? И есть ли что-то не так в приведенном выше коде?

Глядя на: e.target.result содержимое:

data:application/zip;base64,...

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

Ответы [ 2 ]

1 голос
/ 04 марта 2020

Просто хотел поделиться этим для всех, кто хочет сделать это без использования jQuery3 ... основываясь на ответе, опубликованном Мусой: { ссылка }

    $('[download]').on('click', function (e) {
        e.preventDefault();
        showFullScreenLoading();
        var $this = $(this);
        var request = new XMLHttpRequest();
        request.open('GET', $this.attr('href'), true);
        request.responseType = 'blob';
        request.onload = function (e) {
            var data = request.response;
            var blobUrl = window.URL.createObjectURL(data);
            var downloadLink = document.createElement('a');
            downloadLink.href = blobUrl;
            downloadLink.download = $this.attr('download') || 'download';
            downloadLink.click();
            hideFullscreenLoading();
        };
        request.send();
    });
1 голос
/ 03 марта 2020

Если вы загружаете нетекстовый файл (например, zip-файл) через ajax, вы должны указать responseType, двоичный файл, в приведенном ниже примере я задаю его как blob, чтобы данные, которые вы получаете в ответом ajax будет BLOB-объект.
URL-адрес BLOB-объекта создается и используется в привязке вместо громоздких данных URI.

    $.ajax({
        url:download.attr('href'),
        cache:false,
        xhrFields:{
            responseType: 'blob'
        },
        success: function(data){
            var blobUrl = window.URL.createObjectURL(data);
            const anchor = document.createElement('a');
            anchor.style.display = 'none';
            anchor.href = blobUrl;
            anchor.download = 'download.zip';
            anchor.click();
            hideLoading();
        },
        error:function(){

        }
    });

jQuery 3+, необходимых для работы.

...