Скачивание файла из ASP.NET Web API через AngularJS

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Чтобы инициировать загрузку файла из ASP.NET Web API с использованием AngularJS, в первую очередь необходимо подготовить API-метод, отвечающий за передачу файла и установку соответствующих HTTP-заголовков. Затем уже с помощью AngularJS вызываем предварительно настроенный метод, формируем Blob-объект на основе полученных данных и запускаем процесс скачивания путем имитации нажатия на временную ссылку. Если все сделано правильно, ваш код будет работать безупречно с самого начала!

HTTP-запрос и загрузка файла через AngularJS:

JS
Скопировать код
app.service('FileWay', ['$http', function ($http) {
    this.download = function (fileUrl) {
        $http.get(fileUrl, { responseType: 'blob' }).success(function (data, status, headers) {
            var blob = new Blob([data], { type: headers('Content-Type') });
            var downloadLink = angular.element('<a></a>');
            downloadLink.attr('href', window.URL.createObjectURL(blob));
            downloadLink.attr('download', headers('x-filename') || 'PreloadedFile.ext');
            downloadLink[0].click();
        }).error(function () {
            // В процессе загрузки файла возникла ошибка. Попытайтесь загрузить его заново.
        });
    };
}]);

API-метод для передачи файла:

csharp
Скопировать код
public HttpResponseMessage GetFile()
{
    var filePath = HttpContext.Current.Server.MapPath("~/file.ext");
    var result = new HttpResponseMessage(HttpStatusCode.OK);
    var stream = new FileStream(filePath, FileMode.Open);
    result.Content = new StreamContent(stream);
    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
    { FileName = "file.ext" };
    return result;
}

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

Кинга Идем в IT: пошаговый план для смены профессии

Конфигурация типов файлов и заголовков

От типа файла зависит, какой MIME-тип должен быть указан в заголовке Content-Type. Ошибка в нем может вызвать серьезные проблемы. Вот некоторые MIME-типы для популярных форматов файлов:

  • PDF: application/pdf
  • Word: application/msword или application/vnd.openxmlformats-officedocument.wordprocessingml.document для .docx
  • Excel: application/vnd.ms-excel или application/vnd.openxmlformats-officedocument.spreadsheetml.sheet для .xlsx
  • Изображения: image/jpeg для JPEG, image/png для PNG и так далее.

А еще вы можете настроить заголовок Content-Disposition, чтобы указать необходимое имя файла:

csharp
Скопировать код
result.Content.Headers.ContentDisposition.FileName = "CustomFileName.ext";

Использование x-filename, хотя и нестандартное, позволит извлечь имя файла из заголовка Content-Disposition.

JS
Скопировать код
downloadLink.attr('download', headers('Content-Disposition').split(';')[1].split('=')[1]);

Повторно используемые директивы AngularJS для загрузки файлов

Создание пользовательской директивы AngularJS для работы с загрузками файлов улучшает повторное использование кода и инкапсулирует функциональность, благодаря чему вы сможете легко использовать компонент "кнопки загрузки" по всему приложению.

Особенности работы в Internet Explorer

Для обеспечения совместимости с IE 11 нужно использовать navigator.msSaveBlob:

JS
Скопировать код
if (window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveBlob(blob, 'downloadedFile.ext');
} else {
    downloadLink[0].click();
}

Визуализация

Загрузка файла из ASP.NET Web API с использованием AngularJS выглядит следующим образом:

На сервере (🖥️) хранится файл, который нужно загрузить.

Мы инициируем запрос:

http
Скопировать код
GET /api/download/fileID HTTP/1.1
Host: your-api-domain.com

AngularJS (🔽) обрабатывает ответ и предлагает файл пользователю:

JS
Скопировать код
$http({
  url: 'your-api-domain.com/api/download/fileID', 
  method: 'GET',
  responseType: 'arraybuffer'
}).success(function(data) {
  let blob = new Blob([data], { type: 'application/octet-stream' });
  saveAs(blob, 'filename.ext');
});

В итоге ощущение такое, словно сервер напрямую отправляет файл на ваше устройство через AngularJS.

Улучшение пользовательского опыта

Чтобы сделать процесс загрузки более комфортным для пользователя, вы можете добавить:

  • Индикаторы прогресса: анимация, отображающая процесс загрузки.
  • Контроль активности ссылок: деактивация во время загрузки и активация после нее или в случае ошибки.
  • Сообщения об ошибках: ясные указания по действиям при возникновении проблем.

Если речь идет о небольших файлах, их можно загрузить немедленно:

JS
Скопировать код
window.open(fileUrl);

Но будьте осторожны при использовании этого метода, поскольку браузеры могут блокировать всплывающие окна.

Полезные материалы

  1. Сервис $http AngularJS — документация по сервису $http на официальном сайте AngularJS.
  2. Создание и сохранение файла с помощью JavaScript – Stack Overflow — обучающий материал по созданию и сохранению файлов в JavaScript.
  3. GitHub – alferov/angular-file-saver — компонент для обеспечения работы функции saveAs() в AngularJS.
  4. AngularJS Promises – The Definitive Guide — детальное руководство по промисам в AngularJS.
  5. Content-Disposition – HTTP | MDN — описание заголовка Content-Disposition.
  6. JavaScript download file on click – Code Examples & Solutions — примеры инициирования загрузки файлов в JavaScript.
  7. ASP.NET Web API File Download Service With Custom Headers — статья о загрузке файлов в ASP.NET Web API с возможностью установки специальных заголовков.