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

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库简化下载逻辑:

  1. 安装库:npm install file-saver --save
  2. 导入并使用:
import { saveAs } from 'file-saver';

// 在拿到Blob后直接调用
saveAs(blob, 'file.docx');

最后要确认后端返回的响应头Content-Type是application/vnd.openxmlformats-officedocument.wordprocessingml.document,这样浏览器才能正确识别文件类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:06:48