Загрузка файла из Angular и Spring MVC API

Я пытаюсь загрузить файл одним нажатием кнопки в Angular. Файл, который загружается, но имеет размер 0 КБ и не открывается.

Это код, который у меня есть в Angular и Spring MVC.

Угловой:

public downloadFile(fileName:string){
    console.info("ready to download");
    let param:any = {'messageId':this.loadedMessageService.messageId, 'attachmentName':fileName}
    this.http.get(`https://fakeurl.com/abc/getFile`,{params:param,responseType:'blob'}).subscribe(
      (data) => {
        let b:Blob = new Blob([data])
        //,{type: 'application/octet-stream',}
       // const fileName :string= "RL.xlsx" 
        var url = window.URL.createObjectURL(b);
        const a : HTMLAnchorElement = document.createElement('a') as HTMLAnchorElement;
       // const a = document.createElement('a');
        document.body.appendChild(a);
        a.href = url;
        a.download = fileName; 
        a.click();
        document.body.removeChild(a);
       URL.revokeObjectURL(url);
      }
    )
  }

Весенний МВК:

@GetMapping(value = "/getFile")
     public @ResponseBody byte[] getFile() throws IOException {
           try {
                return messageAttachmentService.getFile(Integer.parseInt(request.getParameter("messageId")), request.getParameter("attachmentName"));
           } catch (NumberFormatException e) {
                StringWriter sw = new StringWriter();
                e.printStackTrace(new PrintWriter(sw));
                logger.error(sw.toString());
           } catch (Exception e) {
                StringWriter sw = new StringWriter();
                e.printStackTrace(new PrintWriter(sw));
                logger.error(sw.toString());
           }
           return null;
     }

Прямо сейчас, когда я нажимаю кнопку, файл загружается, но его размер составляет 0 КБ и он не открывается. Раньше я использовал type как application/octet-stream, поскольку загружаемый файл мог быть либо PDF, либо текстовым файлом, либо xls. Я также сослался на другие вопросы и попытался изменить тип ответа на arraybuffer. Это тоже не решило проблему. Что не так с моим кодом?

Что произойдет, если вы пропустите часть Angular и перейдете прямо к URL-адресу загрузки вашего бэкэнда из браузера?

Tarmo 14.05.2019 08:42

В этом случае я загружаю весь файл с расширением «файл». Если я попытаюсь открыть это с помощью Acrobat Reader (поскольку я тестирую PDF-файл), он откроется нормально.

Akshat Sood 14.05.2019 08:45

Ok. В этом случае код на стороне сервера, вероятно, не имеет значения. Почему вы хотите использовать библиотеку/подписку Angular HTTP с загрузкой файла. Не проще ли было просто перейти по ссылке для скачивания по старинке и все заработало?

Tarmo 14.05.2019 08:48

каков вывод console.info(data) на угловой стороне?

rajesh-nitc 14.05.2019 08:53

может быть дубликатом, см. здесь: stackoverflow.com/questions/35138424/…

Senthil 14.05.2019 09:08
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
2
5
383
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете попробовать так.

  public downloadFile(fileName:string){
    console.info("ready to download");
    let param:any = {'messageId':this.loadedMessageService.messageId, 'attachmentName':fileName}
    this.http.get(`https://fakeurl.com/abc/getFile`,{params:param,responseType:'blob'}).subscribe(
      (data) => {
          const a = document.createElement('a');
          document.body.appendChild(a);
          const blob: any = new Blob([data], { type: 'octet/stream' });
          const url = window.URL.createObjectURL(blob);
          a.href = url;
          a.download = data.fileName;
          a.click();
          window.URL.revokeObjectURL(url);
      }
    )
  }

Было бы неплохо, если бы вы добавили свои рассуждения, почему решение OP не работает, а ваше работает. Просто кусок кода не является хорошим ответом, так как трудно понять, почему это может что-то решить.

Tarmo 14.05.2019 08:50
Ответ принят как подходящий

Вы можете попробовать с пакетом файл-сохранитель. Это простой в использовании.

import * as FileSaver from 'file-saver';

const blob: any = new Blob([data], { type: 'octet/stream' });
saveAs(blob, "hello world.txt");

Другие вопросы по теме