Вы можете получить имя файла своего большого двоичного объекта, открыв заголовок ответа и получив Content-Disposition
.
. Для этого измените немного свой вызов HttpClient.get
, предоставив дополнительную опцию observe: 'response'
.
Чтобы прояснить ситуацию, мы создаем выделенный ExportResponse
для предоставления только необходимых данных нашему компоненту / или другому методу обслуживания:
export type ExportResponse = {
blob: Blob,
fileName: string
}
exportRows
возвращает Response Headers
:
exportRows(query): ExportResponse {
return this.http.get(`/api/transactions/export`, {
observe: 'response',
responseType: 'blob'
}.pipe(
map(response => {
const contentDisposition = response.headers.get('content-disposition');
return {
blob: response.body,
fileName: getContentDispositionFileName(contentDisposition)
}
})
);
}
Метод getContentDispositionFileName
отвечает за извлечение имени файла из полученного заголовка:
getContentDispositionFileName(contentDisposition: string) {
let filename = 'default-file-name';
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(contentDisposition);
if (matches != null && matches[1]) {
filename = matches[1].replace(/['"]/g, '');
}
return filename;
}
Этот шаблон RegExp взят из Ответ Зимнего солдата , и извлекает часть имени файла.
Затем вы можете использовать ExportResponse
в своем первоначальном методе:
this.transactionService.exportRows(query).subscribe(response => {
const a = document.createElement('a');
a.href = window.URL.createObjectURL(response.blob);
a.download = response.fileName;
a.click();
});
Важное примечание
Если у вас включен CORS
, Осторожно, чтобы ваш бэкэнд мог отправлять и авторизовать ваш интерфейс для доступа к заголовку Content-Disposition
.
Для этого добавьте Access-Control-Expose-Headers: Content-Disposition
в свой ответ.
response.addHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION);