Как сохранить файл (.xls, .xlsx) с помощью new Blob() в JavaScript

С бэка аяксом беру (xlsx) файл, приходит в виде: responseText

Мне необходимо сохранить его на клиенте. Если сделать без аякса window.open('/api/getbyuuid/0e0ca8e1-176 ...', '_blank'), то файл автоматически скачивается и открывается без проблем. Я же пытаюсь сделать через new Blob():

Ext.Ajax.request({
  url: '/api/ks/share/' + record.id,
  method: 'GET',
  success: function (response, opts) {
    // console.log(response.responseText)
    let type = response.getResponseHeader('Content-Type'),
      blob = new Blob([response.responseText], { type: type }),
      disposition = response.getResponseHeader('Content-Disposition'),
      filename = disposition
        .slice(disposition.indexOf('=') + 1, disposition.length)
        .replace(/['"]/g, '')

    if (typeof window.navigator.msSaveBlob !== 'undefined') {
      window.navigator.msSaveBlob(blob, filename);
    } else if (filename) {
      let URL = window.URL || window.webkitURL,
        downloadUrl = URL.createObjectURL(blob),
        a = document.createElement('a');
      a.href = downloadUrl;
      a.target = '_blank';
      a.download = filename;
      document.body.appendChild(a);
      a.click();
      a.parentNode.removeChild(a);

      setTimeout(() => { URL.revokeObjectURL(downloadUrl) }, 100);
    }
  },
  failure: function (response, opts) {
    console.log(response);
  }
});

Файл сохраняет, но при попытке открыть выдает ошибку:

Ошибка 1

При нажатии на "Да":

Ошибка 2


Ответы (1 шт):

Автор решения: xzdwq

Это работает для меня

fetch('/api/ks/share/' + record.id,)
      .then(resp => resp.blob())
      .then(blob => {
        let URL = window.URL || window.webkitURL,
            downloadUrl = URL.createObjectURL(blob),
            a = document.createElement('a');
        a.href = downloadUrl;
        a.target = '_blank';
        a.download = record.id;
        document.body.appendChild(a);
        a.click();
        a.parentNode.removeChild(a);
        setTimeout(() => { URL.revokeObjectURL(downloadUrl) }, 100);
      })
      .catch((err) => {
        console.log(err);
      });
→ Ссылка