HTTP请求获取PDF时报错Unexpected token % in JSON at position 0如何解决
根因
Angular HttpClient 默认响应解析格式为 json,会强制尝试将所有返回内容转为JSON对象。当前服务端返回的是PDF二进制流,首字符为%,不符合JSON格式规范,因此直接抛出解析错误。
你之前配置的Content-type: 'application/pdf'是请求头,用于告诉服务端你发送的请求体格式,本次是无请求体的GET请求,该配置无效,也不会影响客户端的解析逻辑。
修复步骤
- 第一步:调整请求配置,指定响应类型为Blob
修改getFile方法,新增responseType: 'blob'配置,同时修正RxJS操作符的拼写错误(原代码中catcherror、throwerror应为驼峰格式):
import { catchError } from 'rxjs/operators'; import { throwError } from 'rxjs'; getFile(filename): Observable<Blob> { return this.http.get(`someendpoint/download/${filename}`, { responseType: 'blob' }).pipe( catchError(err => throwError(() => err)) ); }
- 第二步:补充Blob转下载的逻辑
拿到Blob类型的响应后,通过浏览器API创建临时下载链接触发文件保存:
testGet() { const name = 'test.pdf'; this.getFile(name).subscribe((blobRes) => { // 创建临时下载链接 const tempUrl = window.URL.createObjectURL(blobRes); const downloadLink = document.createElement('a'); downloadLink.href = tempUrl; downloadLink.download = name; // 触发下载 downloadLink.click(); // 释放内存,避免泄漏 window.URL.revokeObjectURL(tempUrl); }); }
- 可选:服务端补充响应头配置(Express侧)
为了避免跨域或下载文件名异常问题,可在服务端返回时添加如下响应头:
// S3拉取文件流后设置响应头 res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Disposition', `inline; filename="${filename}"`); // 跨域场景下需暴露Content-Disposition头 res.setHeader('Access-Control-Expose-Headers', 'Content-Disposition');
内容的提问来源于stack exchange,提问作者SkinnyBetas
相关产品推荐
相关产品推荐

