You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Angular调用返回Base64编码Excel文件的AWS API接口时无法正确解析内容的问题求助

Angular调用返回Base64编码Excel文件的AWS API接口时无法正确解析内容的问题求助

大家好,我现在遇到一个棘手的问题:AWS Lambda生成的Base64编码Excel文件,通过API Gateway返回后,在Angular 16里怎么都解析不对,下载的文件要么打不开,要么直接报错说“Response is not a Blob”,但用Insomnia/Postman调用API却能正常下载文件,完全没问题。


问题细节

API返回情况(Insomnia测试正常)

  • 状态码200 OK,响应体是完整的Base64字符串(开头是UEsDBBQAAAAIA...
  • 响应头:
    Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
    Content-Disposition: attachment; filename="suitability-produtos-20251124-150728.xlsx"
    Access-Control-Allow-Origin: *
    

Lambda返回配置

Lambda里我是这么构造响应的,已经设置了isBase64Encoded: true

const response = {
  statusCode: 200,
  isBase64Encoded: true,
  body: base64EncodedFile,
  headers: {
    "Content-Type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    "Content-Disposition": "attachment; filename=\"template.xlsx\"",
    "Access-Control-Allow-Origin": "*"
  }
};
return response;

Angular当前代码(报错:Response is not a Blob)

我原本想用blob类型接收,然后生成下载链接,但直接报错:

this.http.post('https://my-api.com/suitability-produtos-templates', {}, { responseType: 'blob' })
  .subscribe((response: Blob) => {
    const blob = new Blob([response], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
    const link = document.createElement('a');
    link.href = window.URL.createObjectURL(blob);
    link.download = 'template.xlsx';
    link.click();
  });

我已经试过的操作

  • 把Angular的responseType改成textjson等,要么还是报错,要么下载的文件损坏打不开
  • 手动在Angular里把返回的Base64字符串转Blob,但结果文件还是损坏
  • 反复核对API响应头,看起来和Postman里的一致

求助点

  1. 我的Angular代码应该怎么调整,才能正确把Base64响应转成可下载的Excel文件?
  2. 是不是API Gateway或者Lambda的配置还有哪里没做好?比如编码、头信息的问题?


解决方案:分两步调整(Angular端+API Gateway配置检查)

一、Angular端:先接收Base64文本,再解码转Blob

因为API Gateway返回的是Base64编码的字符串(即使Lambda设置了isBase64Encoded: true,前端直接用blob接收可能会因为编码转换逻辑出错),正确的流程是:

  1. responseType设为text,拿到原始的Base64字符串
  2. 把Base64字符串解码成Uint8Array,再转成Blob
  3. 最后生成下载链接并释放内存

调整后的Angular代码:

this.http.post('https://my-api.com/suitability-produtos-templates', {}, { responseType: 'text' })
  .subscribe((base64Data: string) => {
    // 解码Base64字符串
    const byteCharacters = atob(base64Data);
    const byteNumbers = new Array(byteCharacters.length);
    for (let i = 0; i < byteCharacters.length; i++) {
      byteNumbers[i] = byteCharacters.charCodeAt(i);
    }
    const byteArray = new Uint8Array(byteNumbers);
    
    // 生成Blob并触发下载
    const blob = new Blob([byteArray], { 
      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' 
    });
    const link = document.createElement('a');
    link.href = window.URL.createObjectURL(blob);
    // 可选:从响应头中获取原始文件名,更友好
    // const filename = this.extractFilenameFromHeaders(response.headers);
    link.download = 'template.xlsx';
    link.click();
    // 释放URL对象,避免内存泄漏
    window.URL.revokeObjectURL(link.href);
  }, error => {
    console.error('下载出错:', error);
  });

二、API Gateway配置检查(关键!)

很多人会忽略API Gateway的内容处理设置,这是导致前端解析失败的常见原因:

  1. 进入API Gateway控制台,找到对应的POST方法
  2. 点击集成请求,滚动到内容处理部分
  3. 确保选择Passthrough(不要选Convert to binary或其他选项),因为Lambda已经返回了Base64编码的内容,API Gateway只需要透传即可
  4. 检查二进制媒体类型设置:在API Gateway的全局设置页面,添加application/vnd.openxmlformats-officedocument.spreadsheetml.sheet到二进制媒体类型列表,这样API Gateway会正确识别并处理Excel文件的响应头

三、Lambda配置的小优化

你当前的Lambda响应头里的Content-Disposition可以调整,避免双引号的转义问题:

const response = {
  statusCode: 200,
  isBase64Encoded: true,
  body: base64EncodedFile,
  headers: {
    "Content-Type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    // 用单引号包裹文件名,避免双引号的转义问题
    "Content-Disposition": "attachment; filename='template.xlsx'",
    "Access-Control-Allow-Origin": "*",
    // 新增头,明确告知前端内容是Base64编码
    "Content-Transfer-Encoding": "base64"
  }
};
return response;

为什么之前的代码会报错?

你之前用responseType: 'blob'时,API Gateway返回的Base64字符串会被Angular当成普通文本转成Blob,生成的文件实际是Base64文本的二进制形式,自然无法被Excel识别,甚至直接触发“Response is not a Blob”的类型错误。


额外测试建议

  1. 用Chrome开发者工具的网络面板查看API响应体:
    • 如果是乱码(二进制内容),说明API Gateway已经把Base64转成了二进制,这时候前端可以直接用blob接收
    • 如果是可见的Base64字符串,就必须用text接收再解码
  2. 下载文件后,用文本编辑器打开(比如Notepad++):
    • 如果开头是UEsDBBQAAAAIA...这种Base64字符,说明解码步骤没做对
    • 如果是乱码(Excel的二进制内容),说明文件是正常的

按照上面的步骤调整后,应该就能正常下载并打开Excel文件了,有问题可以再补充细节哦!

火山引擎 最新活动