TypeScript下载合同文件时遇JSON解析错误:Unexpected token P in JSON
解决合同下载GET接口的JSON解析错误问题
我刚看到你的问题——用Postman调用合同下载GET接口没问题,但自己写的Angular服务代码调用时却抛出response.json() --> Unexpected token P in JSON错误,对吧?
先给你拆解下问题根源:这个错误核心是你在尝试把非JSON格式的响应解析成JSON。合同下载接口返回的应该是二进制文件(比如PDF,开头的字符是P,对应PDF文件头的%PDF-),而你的代码默认让Angular把响应当成JSON来解析,自然就会报错。
下面是具体的修复方案和代码调整:
1. 修改HTTP请求的响应类型
你需要明确告诉Angular,这个接口返回的是二进制文件,不是JSON。在GET请求里设置responseType为blob或者arraybuffer(推荐用blob,更适合处理文件)。
2. 调整服务方法的返回类型
原来的Observable<Sale[]>显然不对,因为返回的不是Sale数组,而是文件Blob,所以要改成Observable<Blob>。
修改后的服务代码示例
import { Headers, RequestOptions, ResponseContentType } from '@angular/http'; // 记得导入对应的依赖 public contract_download(id: string): Observable<Blob> { let headers = new Headers(); headers.append('x-access-token', this.auth.getCurrentUser().token); headers.append('_id', id); // 配置请求选项,指定响应类型为Blob const requestOptions = new RequestOptions({ headers: headers, responseType: ResponseContentType.Blob }); // 替换成你的实际接口URL return this.http.get(Api.getUrl(ApiUrl.CONTRACT_DOWNLOAD), requestOptions) .map(response => response.blob()) .catch(error => { console.error('合同下载请求出错:', error); return Observable.throw(error); }); }
3. 调用服务后处理文件下载
拿到Blob对象后,你需要通过前端代码触发浏览器的下载行为:
// 假设你在组件里调用服务 this.yourContractService.contract_download('目标合同ID').subscribe(blob => { // 创建Blob的临时URL const fileUrl = window.URL.createObjectURL(blob); // 创建a标签触发下载 const downloadLink = document.createElement('a'); downloadLink.href = fileUrl; // 设置下载的文件名,根据实际文件类型调整后缀 downloadLink.download = `合同_${id}.pdf`; document.body.appendChild(downloadLink); downloadLink.click(); // 清理临时URL和DOM元素 window.URL.revokeObjectURL(fileUrl); document.body.removeChild(downloadLink); }, error => { alert('合同下载失败,请稍后重试'); });
补充说明
为什么Postman能正常工作?因为Postman会自动识别响应的Content-Type(比如application/pdf),并自动处理成文件下载,而Angular默认的响应类型是json,所以必须手动指定responseType才能正确处理文件响应。
内容的提问来源于stack exchange,提问作者OnnaB
相关产品推荐
相关产品推荐

