Подтвердить что ты не робот

Загрузка файла из результата ajax с использованием blob

Я использую этот код для загрузки файла excel с сервера.

$.ajax({
    headers: CLIENT.authorize(),
    url: '/server/url',
    type: 'POST',
    contentType: "application/json; charset=utf-8",
    data: JSON.stringify(jsonData),
    success: function (data) {
        alert('Data size: ' + data.length);
        var blob = new Blob([data], { type: "application/vnd.ms-excel" });
        alert('BLOB SIZE: ' + data.length);
        var URL = window.URL || window.webkitURL;
        var downloadUrl = URL.createObjectURL(blob);
        document.location = downloadUrl;
    },
});

Проблема, с которой я сталкиваюсь, заключается в том, что даже если данные и размеры блоба идентичны, момент, когда document.location присваивается, мне предлагается загрузить почти в два раза больше файла excel. И когда я пытаюсь открыть его, excel жалуется на неправильный формат файла, и открытый файл содержит много мусора, хотя требуемый текст все еще существует.

Любые идеи, что вызывает это и как его избежать?

4b9b3361

Ответ 1

Итак, я решил проблему с помощью AJAX 2. Он поддерживает бинарные потоки. Вы не можете использовать jQuery для этого, если только вы base64 не кодируете все, видимо.

Рабочий код выглядит следующим образом:

var xhr = new XMLHttpRequest();
xhr.open('POST', '/le/url', true);
xhr.responseType = 'blob';
$.each(SERVER.authorization(), function(k, v) {
    xhr.setRequestHeader(k, v);
});
xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8');
xhr.onload = function(e) {
    preloader.modal('hide');
    if (this.status == 200) {
        var blob = new Blob([this.response], {type: 'application/vnd.ms-excel'});
        var downloadUrl = URL.createObjectURL(blob);
        var a = document.createElement("a");
        a.href = downloadUrl;
        a.download = "data.xls";
        document.body.appendChild(a);
        a.click();
    } else {
        alert('Unable to download excel.')
    }
};
xhr.send(JSON.stringify(jsonData));

Надеюсь, что это поможет.