Angular下载docx文件报错:Unexpected token P in JSON at position 0
解决Angular下载docx文件时JSON解析错误的问题
你遇到的Unexpected token P in JSON at position 0错误其实很好理解——你把二进制的docx文件当成JSON来解析了!Postman会自动识别响应是文件类型并处理下载流程,但你的代码里调用了response.json(),这会试图把docx的二进制数据转换成JSON对象,显然会失败,因为docx内容根本不是JSON格式。
下面给你两种修改方案,对应Angular的旧版Http和新版HttpClient:
方案1:使用旧版Http模块
首先要导入ResponseContentType,然后在请求里指定响应类型为Blob,最后处理Blob触发下载:
import { Headers, Http, ResponseContentType } from '@angular/http'; public download(id: string): Observable<any> { let headers = new Headers(); headers.append('x-access-token', this.auth.getCurrentUser().token); headers.append('id', id); return this.http.get(Api.getUrl(Api.URLS.download), { headers: headers, responseType: ResponseContentType.Blob // 关键:指定响应为二进制Blob }) .map((response: Response) => { // 构造docx对应的Blob对象 const docxBlob = new Blob([response.blob()], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }); // 触发浏览器下载 const downloadUrl = window.URL.createObjectURL(docxBlob); const link = document.createElement('a'); link.href = downloadUrl; link.download = 'file.docx'; // 设置下载后的文件名 document.body.appendChild(link); link.click(); // 清理临时URL和DOM元素 window.URL.revokeObjectURL(downloadUrl); document.body.removeChild(link); }) .catch(error => { console.error('下载失败:', error); return Observable.throw(error); }); }
方案2:使用新版HttpClient模块
新版HttpClient的响应类型设置更直接,用responseType: 'blob'即可:
import { HttpClient, HttpHeaders } from '@angular/common/http'; public download(id: string): void { const headers = new HttpHeaders() .append('x-access-token', this.auth.getCurrentUser().token) .append('id', id); this.http.get(Api.getUrl(Api.URLS.download), { headers: headers, responseType: 'blob' as 'json' // 类型断言避免TypeScript报错 }) .subscribe( (blob: Blob) => { const downloadUrl = window.URL.createObjectURL(blob); const link = document.createElement('a'); link.href = downloadUrl; link.download = 'file.docx'; document.body.appendChild(link); link.click(); window.URL.revokeObjectURL(downloadUrl); document.body.removeChild(link); }, error => console.error('下载出错:', error) ); }
额外小技巧
如果你觉得手动创建a标签的代码太繁琐,可以使用file-saver库简化下载逻辑:
- 安装库:
npm install file-saver --save - 导入并使用:
import { saveAs } from 'file-saver'; // 在拿到Blob后直接调用 saveAs(blob, 'file.docx');
最后要确认后端返回的响应头Content-Type是application/vnd.openxmlformats-officedocument.wordprocessingml.document,这样浏览器才能正确识别文件类型。
内容的提问来源于stack exchange,提问作者OnnaB
相关产品推荐
相关产品推荐

