Angular Http 客户端文件下载 - 响应中的文件名

问题描述 投票:0回答:2

我正在尝试从 api url 获取文件。我的目标是在输入文件字段中显示该文件(之前上传的)及其名称。目前我已经创建了以下服务功能:

  getDocument(): Observable<Blob> {
    const request = this.documentUrl;
    return this.http.get(request, { responseType: 'blob' });
  }

当我使用它时

    this.myService.getDocument().subscribe(
      response => {
        console.log(response);
      }

我得到一个 Blob,根据定义,它没有名称。我已经看到我可以将其转换为文件并为其命名,但此解决方案不符合我的需要。有没有办法可以从后端获取文件,或者有没有办法用 Blob 的原始名称重建它?

angular
2个回答
4
投票

请确保后端API在响应头中设置了文件名。通常,文件名包含在

content-disposition
标头中。

例如:看起来像

content-disposition: attachment;filename=XYZ.csv

在 Angular 中,您可以像下面这样提取它:

.subscribe((response: HttpResponse<Blob>) => {
  // Extract content disposition header
  const contentDisposition = response.headers.get('content-disposition');

  // Extract the file name
  const filename = contentDisposition
        .split(';')[1]
        .split('filename')[1]
        .split('=')[1]
        .trim()
        .match(/"([^"]+)"/)[1];
});

0
投票

请确保后端API在响应头中设置了文件名。通常,文件名包含在内容处置标头中。

  • 如果您使用 CORS,请确保公开您的标头。

我发现这要归功于this答案以及thisCORS策略不允许Angular查看所有标头,我使用Java作为后端,这就是我解决问题的方法:

角度:

this.myService.downloadBlob(BlobID).subscribe(
      (response: HttpResponse<Blob>) => {
        //same code as andsilver
        // Extract content disposition header
        const contentDisposition = response.headers.get('content-disposition');
        // Rest of your code to extract filename using contentDisposition
        // Extract the file name
        const filename = contentDisposition
          .split(';')[1]
          .split('filename')[1]
          .split('=')[1]
          .trim();
        this.downloadBlob(new Blob([(response.body)], { type: 'text/plain' }), filename);
      }

服务角度:

downloadBlob(BlobID: number): Observable<HttpResponse<Blob>> {
        return this.http.get(myUrl+'?BlobID='+BlobID, { observe: 'response', responseType: 'blob' });
    }

服务器端(在我的例子中是Java):

@GetMapping("/downloadBlob")
    public ResponseEntity<byte[]> downloadBlob(@RequestParam("BlobID") BigDecimal BlobID) {
            
            BlobAndName blobAndName = service.getDocumento(BlobID);
            byte[] blobAsBytes = Utils.blob2ByteArray(blobAndName.getBlob());
            HttpHeaders head = new HttpHeaders();
            head.add("content-disposition", "attachment; filename=" + blobAndName.getName());
            ArrayList<String> exposedHead = new ArrayList<>();
            exposedHead.add("content-disposition");
            head.setAccessControlExposeHeaders(exposedHead);
            return ResponseEntity.ok().headers(head).body(blobAsBytes);
    }

我必须说,由于我的同事的安全问题(没有向我解释,所以我什至不知道它们是什么),这不是我实现的解决方案,我通过不同的方法获得了名称和 blob因为我有机会通过回收以前的一个来做到这一点,它已经为我提供了我需要的不同信息,现在也为我提供了 blob 名称。

© www.soinside.com 2019 - 2024. All rights reserved.