Как я могу перейти к внешнему параметру URL?

#angular #typescript #url #redirect #blob

#angular #typescript #url #перенаправление #большой двоичный объект

Вопрос:

Итак, я пытался перенаправить URL-адрес и открыть его на новой вкладке, но мне это не удалось.

У меня есть API, который возвращает мне обычный текст, который отображается как объект BLOB, но на самом деле это просто URL. Мне нужно открыть этот URL-адрес в новой вкладке.

Это код, который я пытаюсь заставить работать:

     this.printingService.getCvUrl(options).subscribe(
      url => {
        const downloadURL = window.URL.createObjectURL(url);
        window.open(downloadURL, '_blank');
      }
    );
 

Он вызывает метод getCvUrl, что это:

    getCvUrl(options: { remoteUrl: string, paperHeight?: string, paperWidth?: string }): Observable<any> {
    const user = this.authenticationService.getCurrentUser();
    const PRINT_SERVICE = `/api/users/${user.id}/syncMyCV`;
    const CV_SERVICE = 'https://cv.url/template/ce';

    const formData = new FormData();
    formData.append('remoteURL', CV_SERVICE   options.remoteUrl);
    formData.append('paperHeight', options.paperHeight);
    formData.append('paperWidth', options.paperWidth);

    const token = this.authenticationService.getToken();

    return this.http.post(
      PRINT_SERVICE,
      formData,
      {
        headers: {
          'Anonymous': 'undefined',
          'accept': '*/*',
          'Authorization': token
        },
        responseType: 'blob'
      }
    ).pipe(catchError(err => {
      this.errorService.handleError(err);
      return observableOf(null);
    }));
  }
 

В качестве ответа в настоящее время для меня открывается новая вкладка с текстом URL-адреса в качестве содержимого, но не в поле URL-адреса браузера.

Я пробовал все эти подходы:

Сначала я попробовал перемещаться с помощью маршрутизатора, но, конечно, это не сработало, так как я пытаюсь открыть внешний URL-адрес.

     this.printingService.getCvUrl(options).subscribe(
      url => this.router.navigate([url])
    );
 

Затем, рассмотрев некоторые вопросы, я попытался изменить атрибут href расположения окна. Это тоже не сработало

     this.printingService.getCvUrl(options).subscribe(
      url => window.location.href = url
    );
 

Затем, следуя другому ответу, я перешел на метод открытия окна, и он открыл новую вкладку, но затем выдал мне ошибку 404

     this.printingService.getCvUrl(options).subscribe(
      url => window.open(url, '_blank')
    );
 

Просмотрев его, я понял, что пытаюсь перенаправить объект blob, как если бы это была строка URL, поэтому потребовалось некоторое преобразование. Затем я попытался использовать метод, который я создал в той же службе, которую я использую.

     this.printingService.getCvUrl(options).subscribe(
      url => {
        this.printingService.view(url);
      }
    );
 

И затем он вызвал метод view() в службе печати, который реализован следующим образом:

     view(data: ArrayBuffer, filename = 'resume.pdf') {
    if (!!data) {
      const blob = new Blob([data], {type: 'application/pdf'});
      const downloadURL = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = downloadURL;
      link.download = filename;
      link.click();
    }
  }
 

Но проблема в том, что этот метод загружает PDF-файл, но это даже не то, что я хочу, поэтому я решил взять то, что мне нужно, из этого метода и адаптировать его. Затем я перешел к текущему решению выше, которое тоже не работает:

     this.printingService.getCvUrl(options).subscribe(
      url => {
        const downloadURL = window.URL.createObjectURL(url);
        window.open(downloadURL, '_blank');
      }
    );
 

До этого момента у меня не было идей. Есть ли у кого-нибудь другой подход, который я не пробовал?


Решение с использованием принятого ответа:

В методе getCvUrl я изменил эту строку:

 responseType: 'blob'
 

этим:

 responseType: 'text'
 

поскольку ответ, поступающий от API, всегда будет текстовым / простым ответом. И окончательный код выглядит так:

     this.printingService.getCvUrl(options).subscribe(
      url => {
        const downloadLink = document.createElement('a');
        downloadLink.href = url;
        document.body.appendChild(downloadLink);
        downloadLink.click();
        document.body.removeChild(downloadLink);
      }
    );
 

Комментарии:

1. Удаление этого link.download = filename; download атрибута настройки строки загрузит файл вместо открытия в новой вкладке

2. Спасибо @Prabh как вы можете видеть в последнем обновленном фрагменте, я его не использовал

Ответ №1:

Я не уверен, что это сработает, но попробуйте добавить элемент link в DOM, прежде чем щелкнуть по нему, а затем удалить его.

 function openBlob(data: Blob) {
  //Add a link and click it!
  const downloadLink = document.createElement("a");
  downloadLink.href = window.URL.createObjectURL(data);
  downloadLink.download = filename;
  document.body.appendChild(downloadLink);
  downloadLink.click();
  document.body.removeChild(downloadLink);
}
 

Ответ №2:

попробуйте использовать этот пакет для сохранения файлов

это легко реализовать.

 import { saveAs } from 'file-saver';

 this.http
  .post(
    yourURL
    {
      responseType: 'arraybuffer',
    }
  )
  .subscribe((val: any) => {
    const blob = new Blob([val], { type: 'application/pdf' });
    const url = window.URL.createObjectURL(blob);
    saveAs(blob, 'name.pdf');
  });