Nuestros mejores programadores han agotado sus depósitos de café, por su búsqueda todo el tiempo por la resolución, hasta que César encontró el arreglo en GitLab así que hoy la compartimos aquí.
Solución:
Los blobs se devuelven con el tipo de archivo del backend. La siguiente función aceptará cualquier tipo de archivo y ventana emergente de descarga:
downloadFile(route: string, filename: string = null): void
const baseUrl = 'http://myserver/index.php/api';
const token = 'my JWT';
const headers = new HttpHeaders().set('authorization','Bearer '+token);
this.http.get(baseUrl + route,headers, responseType: 'blob' as 'json').subscribe(
(response: any) =>
let dataType = response.type;
let binaryData = [];
binaryData.push(response);
let downloadLink = document.createElement('a');
downloadLink.href = window.URL.createObjectURL(new Blob(binaryData, type: dataType));
if (filename)
downloadLink.setAttribute('download', filename);
document.body.appendChild(downloadLink);
downloadLink.click();
)
Prueba algo como esto:
tipo: aplicación/ms-excel
/**
* used to get file from server
*/
this.http.get(`$environment.apiUrl`,
responseType: 'arraybuffer',headers:headers
).subscribe(response => this.downLoadFile(response, "application/ms-excel"));
/**
* Method is use to download file.
* @param data - Array Buffer data
* @param type - type of the document.
*/
downLoadFile(data: any, type: string)
let blob = new Blob([data], type: type);
let url = window.URL.createObjectURL(blob);
let pwa = window.open(url);
if (!pwa
Me tomó un tiempo implementar las otras respuestas, ya que Estoy usando Angular 8 (probado hasta 10). Terminé con el siguiente código (muy inspirado en Hasan).
Tenga en cuenta que para que se establezca el nombre, el encabezado Access-Control-Expose-Headers
Debe incluir Content-Disposition
. Para configurar esto en django RF:
http_response = HttpResponse(package, content_type='application/javascript')
http_response['Content-Disposition'] = 'attachment; filename=""'.format(filename)
http_response['Access-Control-Expose-Headers'] = "Content-Disposition"
en angulares:
// component.ts
// getFileName not necessary, you can just set this as a string if you wish
getFileName(response: HttpResponse)
let filename: string;
try
const contentDisposition: string = response.headers.get('content-disposition');
const r = /(?:filename=")(.+)(?:")/
filename = r.exec(contentDisposition)[1];
catch (e)
filename = 'myfile.txt'
return filename
downloadFile()
this._fileService.downloadFile(this.file.uuid)
.subscribe(
(response: HttpResponse) =>
let filename: string = this.getFileName(response)
let binaryData = [];
binaryData.push(response.body);
let downloadLink = document.createElement('a');
downloadLink.href = window.URL.createObjectURL(new Blob(binaryData, type: 'blob' ));
downloadLink.setAttribute('download', filename);
document.body.appendChild(downloadLink);
downloadLink.click();
)
// service.ts
downloadFile(uuid: string)
return this._http.get(`$environment.apiUrl/api/v1/file/$uuid/package/`, observe: 'response', responseType: 'blob' as 'json' )
Si haces scroll puedes encontrar las anotaciones de otros usuarios, tú además eres capaz insertar el tuyo si te gusta.