#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');
});