Этот вопрос проверяет понимание ограничений браузера при работе с HTTP-запросами и различий между пользовательскими и программными запросами.
Когда пользователь кликает на обычную ссылку или вы используете window.location.href для перехода, браузер создаёт простой GET-запрос, в который он сам добавляет стандартные заголовки (User-Agent, Accept и т.д.). Добавить произвольные заголовки, такие как Authorization: Bearer <token>, в этот запрос невозможно, потому что это нарушило бы модель безопасности браузера.
Нужно использовать JavaScript для создания программного запроса, получить данные как Blob, а затем создать ссылку для скачивания.
async function downloadFileWithAuth(url, token) {
const response = await fetch(url, {
headers: {
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) throw new Error('Download failed');
const blob = await response.blob();
const downloadUrl = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = downloadUrl;
link.download = 'file.pdf'; // имя файла
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(downloadUrl);
}Этот метод безопасен, потому что заголовки контролируются в контексте текущей страницы и подчиняются правилам CORS.
Такой подход необходим в современных SPA-приложениях (React, Angular, Vue), где аутентификация происходит через JWT-токены, а API требует передачи токена в заголовке Authorization для доступа к защищённым ресурсам, включая файлы.
Вывод: Используйте Fetch API (или аналоги) для скачивания файлов, требующих авторизации, так как только программные запросы позволяют полностью контролировать HTTP-заголовки, соблюдая при этом политики безопасности браузера.