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

Angular接收Java返回CSV文件失败问题求助及解决反馈

解决CSV导出API返回正确数据但浏览器不触发下载且解析失败的问题

我遇到了一个CSV导出的问题:后端REST API返回状态码200且响应体数据正确,但浏览器无法触发文件下载,同时Angular端报错Error downloading the file.Http failure during parsing for myURL。

后端API代码(Java Spring)

ResponseEntity<Resource> exportCsv() throws IOException { 
    InputStreamResource resource = new InputStreamResource(new FileInputStream(file)); 
    HttpHeaders headers = new HttpHeaders(); 
    headers.add("Content-disposition", "attachment; filename=sample.csv"); 
    headers.add("Cache-Control", "no-cache, no-store, must-revalidate"); 
    headers.add("Pragma", "no-cache"); 
    headers.add("Expires", "0"); 
    return ResponseEntity.ok() 
        .headers(headers) 
        .contentLength(file.length()) 
        .contentType(MediaType.parseMediaType("text/csv")) 
        .body(resource); 
}

Angular前端代码

Service中的请求方法

exportCsv( stickSearch: StickSearch ): Observable<any> { 
    const headers = this.oAuthService.putTokenInHeaders(this.headers); 
    let params = new HttpParams({encoder: new HttpURIEncoder()}); 
    if (stickSearch.searchString() !== '') { 
        params = params.append('search', stickSearch.searchString()) 
    } 
    return this.httpClient.get(this.exportCsvUrl + '/exportCsv', { 
        responseType: 'text', 
        params: params, 
        headers 
    }); 
}

组件中的调用与下载方法

this.stickService.exportCsv( this.stickSearch )
    .subscribe( response => this.downloadFile(response), 
                err => console.log('Error downloading the file.' + err.message ));

downloadFile(data: Response) { 
    const blob = new Blob([data], { type: 'text/csv' }); 
    const url = window.URL.createObjectURL(blob); 
    window.open(url); 
}

问题原因

报错的核心原因是Angular请求的responseType设置错误:后端返回的是文件流(二进制形式的CSV),但前端设置了responseType: 'text',Angular会尝试将二进制流解析为UTF-8字符串,这个解析过程会失败,从而抛出Http failure during parsing错误。另外,用window.open()触发下载的方式也不够可靠,容易被浏览器拦截,且没有明确指定文件名。

解决方法

1. 修改Angular请求的responseType为blob

将Service中的请求方法改为直接获取Blob类型的响应,避免解析错误:

exportCsv( stickSearch: StickSearch ): Observable<Blob> { 
    const headers = this.oAuthService.putTokenInHeaders(this.headers); 
    let params = new HttpParams({encoder: new HttpURIEncoder()}); 
    if (stickSearch.searchString() !== '') { 
        params = params.append('search', stickSearch.searchString()) 
    } 
    return this.httpClient.get(this.exportCsvUrl + '/exportCsv', { 
        responseType: 'blob', // 改为blob类型,直接获取文件流
        params: params, 
        headers 
    }); 
}

2. 优化下载方法,通过创建a标签触发下载

替换原有的downloadFile方法,使用更可靠的a标签方式,确保浏览器识别下载行为并指定文件名:

downloadFile(blob: Blob) { 
    const url = window.URL.createObjectURL(blob); 
    const downloadLink = document.createElement('a'); 
    downloadLink.href = url; 
    downloadLink.download = 'sample.csv'; // 与后端响应头指定的文件名保持一致
    document.body.appendChild(downloadLink); 
    downloadLink.click(); 
    // 清理临时资源
    window.URL.revokeObjectURL(url); 
    document.body.removeChild(downloadLink); 
}

这样修改后,前端就能正确获取到文件流,通过a标签触发浏览器的下载行为,同时彻底解决了解析错误的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:34:42