Здравствуйте! Нужно отправить запрос на сервер с помощью метода fetch. При неудаче получить json ответ с ошибкой, при успехе, нужно, чтобы начал скачиваться файл.
Сейчас я реализовал функцию следующим образом:
static async downloadReport(startDate, endDate, shopsIds) {
try {
const url = `${Helper.getLocation()}/api/shops/reports/download-report?`
+ `start_date=${startDate}`
+ `&end_date=${endDate}`
+ `&shops_ids=${shopsIds}`;
const response = await fetch(url);
if (response.status === 200) {
const blob = await response.blob();
const downloadUrl = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = downloadUrl;
link.download = `report_${startDate}-${endDate}.xlsx`;
document.body.appendChild(link);
link.click();
link.remove();
setTimeout(() => {
// For Firefox it is necessary to delay revoking the ObjectURL.
// https://bugzilla.mozilla.org/show_bug.cgi?id=1282407
window.URL.revokeObjectURL(blobUrl);
}, 100);
return true;
}
const result = await response.json();
result.data.errors.forEach((item) => {
toast(item.message, 'error');
});
} catch (error) {
toast(error, 'error');
}
return false;
}
Проблема в том, что это решение похоже на костыльное. Так как нужно создавать элемент ссылку, имитировать нажатие на неё, а затем удалять ссылку. Подозрения, что не везде такой подход будет работать. Подскажите, есть ли более правильное решение для данной ситуации.
Дополнение
Поискал дополнительно по теме. Все делают именно таким способом, то есть создают элемент ссылку и имитируют клик. Может в будущем будет какой-то другой вариант для таких случаев.