You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot PNG下载接口在Angular中返回undefined的问题

Angular获取PNG接口返回undefined的解决办法

问题背景

Spring Boot后端提供PNG签名文件下载接口,Postman及浏览器网络面板可正常获取响应,但Angular订阅接口后始终得到undefined。

后端代码:

@GetMapping(value = "downloadsignature", produces = "image/png")
public ResponseEntity downloadSignature(HttpServletRequest request) {
  var user = getUserOfRequest();
  try {
    var resource = signFileStorage.loadFileAsResource(user.getSignatureImageFile());
    return ResponseEntity.ok().contentType(MediaType.parseMediaType(request.getServletContext()
                                                                           .getMimeType(resource.getFile()
                                                                                                .getAbsolutePath())))
                         .header(HttpHeaders.CONTENT_DISPOSITION,
                                 "attachment; filename=\"" + resource.getFilename() + "\"")
                         .body(new InputStreamResource(resource.getInputStream()));
  } catch (Exception e) {
    logger.error(e.getMessage());
    return ResponseEntity.badRequest().body("error.signature_cannot_read");
  }
}

原Angular服务代码:

public downloadSignature(): Observable<Blob> {
  return this.http.get<Blob>(`${this.getURL()}/downloadsignature`);
}

原Angular组件调用代码:

ngOnInit(): void {
  this.profileService
    .downloadSignature()
    .pipe(catchError((error) => of(this.processError(error))))
    .subscribe((item) => {
      console.log(item);
    });
}

问题原因

Angular HttpClient默认会将响应解析为JSON格式,而后端返回的是二进制PNG数据,解析失败后返回undefined。必须显式指定响应类型为blob才能正确处理二进制数据。

解决方案

1. 修正Angular服务代码

在get请求中添加responseType: 'blob'配置,明确告知HttpClient处理二进制Blob数据:

public downloadSignature(): Observable<Blob> {
  return this.http.get(`${this.getURL()}/downloadsignature`, {
    responseType: 'blob' // 关键配置:指定响应类型
  });
}

2. 组件内正确处理响应

如果需要触发前端下载,可以在订阅后创建临时链接实现:

ngOnInit(): void {
  this.profileService
    .downloadSignature()
    .pipe(catchError((error) => {
      this.processError(error);
      return of(null);
    }))
    .subscribe((blob) => {
      if (blob) {
        console.log(blob); // 现在能正常获取Blob对象
        // 触发文件下载
        const downloadUrl = window.URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = downloadUrl;
        link.download = 'signature.png'; // 设置下载文件名
        document.body.appendChild(link);
        link.click();
        // 清理资源
        window.URL.revokeObjectURL(downloadUrl);
        document.body.removeChild(link);
      }
    });
}

3. 后端可选优化(规范写法)

后端已通过produces = "image/png"声明响应类型,可直接使用MediaType.IMAGE_PNG代替通过ServletContext获取MimeType,避免潜在问题:

@GetMapping(value = "downloadsignature", produces = "image/png")
public ResponseEntity downloadSignature(HttpServletRequest request) {
  var user = getUserOfRequest();
  try {
    var resource = signFileStorage.loadFileAsResource(user.getSignatureImageFile());
    return ResponseEntity.ok()
        .contentType(MediaType.IMAGE_PNG)
        .header(HttpHeaders.CONTENT_DISPOSITION,
                "attachment; filename=\"" + resource.getFilename() + "\"")
        .body(new InputStreamResource(resource.getInputStream()));
  } catch (Exception e) {
    logger.error(e.getMessage());
    return ResponseEntity.badRequest().body("error.signature_cannot_read");
  }
}

内容的提问来源于stack exchange,提问作者Ossama Nasser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 13:32:04