Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

282
Vistas
How do I programmatically download a file using the browser's native download widget in Angular?

So, when I request my webservice for getting download a zip file, it downloads the file content secretely and all of a sudden, the file appears in the download task bar but already downloaded full (100%)

Using the following angular method:


const endpoint = "http://localhost:8080/download/zip"
this.http.get<Blop>(endpoint, {headers: httpHeaders, responseType: 'blob', reportProgress: true })

So here is how I am subscribing:

this.http.get<Blop>(endpoint, {headers: httpHeaders, responseType: 'blob', reportProgress: true }).subscribe({
  next: data => {
    console.log('blocking or not');
    const blob = new Blob([data as any], { type: 'application/zip' });
    window.location.href = URL.createObjectURL(blob);
  }
})

So I noticed my console.log(...) isn't called until the end of the download, so I suppose that the browser-ui can't detect the download until it reaches window.location.href.

How to force the download to be shown in the download task bar before the end of the transfert, and watch the download progress in the browser? I coudld not find anything related to async blop or something like that.

PS: my backend is serving a stream of data, so the backend is not the problem. When calling my api directly through the browser, we can see the download progress in the download task bar. Still, if you guys are interested, this is the snippet (spring-boot)

    @GetMapping("/download/zip")
    fun download(response: HttpServletResponse): StreamingResponseBody {
        val file = downloads.download("launcher")

        response.contentType = "application/zip"
        response.setHeader(
            "Content-Disposition",
            "attachment;filename=sample.zip"
        )
        response.setContentLengthLong(file.length())

        return StreamingResponseBody { outputStream: OutputStream ->
            var bytesRead: Int
            val buffer = ByteArray(2048)
            val inputStream: InputStream = file.inputStream()
            while (inputStream.read(buffer).also { bytesRead = it } != -1) {
                outputStream.write(buffer, 0, bytesRead)
            }
        }
    }
about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

For download you have 2 ways:

  1. http.get + msSaveOrOpenBlob (if its defined)/createObjectURL
  • you have full control over request, process and errors. E.g. u can cancel request, add additional headers, etc.
  • download remains in your app flow, e.g. F5 will cancel it.
  1. create hidden download link and click it programatically
  • you cannot add headers, you cannot show progress/errors in simple way (there are some tricks involving additional cookies to set by BE)
  • Its strated as separate process, e.g. you can close your app tab or whatever.

There seems to be no chance of mixing these 2 approaches and in general I would say 1st one is more modern and preferable for small files, however if you are not happy with it try 2nd one (https://stackoverflow.com/a/49917066/4019404):

function download(url) {
  const a = document.createElement('a')
  a.href = url
  a.download = url.split('/').pop()
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
}
about 4 years ago · Juan Pablo Isaza Denunciar

0

Assuming you are using Angular's HttpClient, something like this should work:

    const endpoint = "http://localhost:8080/download/zip"
    const req = new HttpRequest('GET', endpoint, { reportProgress: true, })
    this.Http.request(req).subscribe(event => {
      if (event.type === HttpEventType.DownloadProgress) {
        const percentDone = Math.round(100 * event.loaded / (event.total || 0))
        console.log(percentDone);
      } else if (event instanceof HttpResponse) {
        const blob = new Blob([event.body as any], { type: 'application/zip' });
        window.location.href = URL.createObjectURL(blob);
      }
    })
about 4 years ago · Juan Pablo Isaza Denunciar

0

You can simply use this package

npm i ngx-filesaver

and

constructor(private _http: Http, private _FileSaverService: FileSaverService) {
}

onSave() {
  this._http.get('yourfile.png', {
    responseType: ResponseContentType.Blob // This must be a Blob type
  }).subscribe(res => {
    this._FileSaverService.save((<any>res)._body, fileName);
  });
}

complete doc here ngx file saver and also file saver.js

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda