Angular: How to download a file from HttpClient?

后端 未结 6 1609
挽巷
挽巷 2020-12-04 23:57

I need download an excel from my backend, its returned a file.

When I do the request I get the error:

TypeError: You provided \'undefined\' wh

6条回答
  •  春和景丽
    2020-12-05 00:10

    It took me a while to implement the other responses, as I'm using Angular 8 (tested up to 10). I ended up with the following code (heavily inspired by Hasan).

    Note that for the name to be set, the header Access-Control-Expose-Headers MUST include Content-Disposition. To set this in 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"
    

    In angular:

      // 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' })
      }
    
    

提交回复
热议问题