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

Angular调用Node服务获取S3 PDF文件显示空白问题排查

问题原因

你在Node服务里把S3返回的二进制PDF数据转成了UTF-8字符串,这会破坏PDF的二进制结构——UTF-8是文本编码,无法正确保留二进制文件的原始字节,传到前端后生成的Blob自然无效,所以打开后显示空白。

解决方案

1. 修改Node端代码,保留二进制数据

不要将S3返回的流转成UTF-8字符串,直接返回二进制Buffer或者将流直接pipe到HTTP响应:

方式一:返回Buffer(适合小文件)

替换原流处理函数和读取逻辑:

// 替换原streamToString为streamToBuffer,直接返回Buffer
const streamToBuffer = (stream) =>
  new Promise((resolve, reject) => {
    const chunks = [];
    stream.on("data", (chunk) => chunks.push(chunk));
    stream.on("error", reject);
    stream.on("end", () => resolve(Buffer.concat(chunks)));
  });

const readFile = async function getObj(key) {
  const params = {
    Bucket: vBucket,
    Key: key,
  };
  const command = new GetObjectCommand(params);
  const response = await client.send(command);
  return streamToBuffer(response.Body);
};

// 假设用Express搭建接口,返回Buffer并设置正确的Content-Type
app.get('/getfile', async (req, res) => {
  const key = req.query.key;
  try {
    const pdfBuffer = await readFile(key);
    res.set('Content-Type', 'application/pdf');
    res.send(pdfBuffer);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

方式二:直接将S3流pipe到响应(适合大文件,更高效)

这种方式无需把整个文件加载到内存,直接将S3的输出流转发给前端:

const readFile = async function getObj(res, key) {
  const params = {
    Bucket: vBucket,
    Key: key,
  };
  const command = new GetObjectCommand(params);
  const response = await client.send(command);
  
  res.set('Content-Type', 'application/pdf');
  // 将S3的流直接pipe到HTTP响应
  response.Body.pipe(res);
};

// 接口处理逻辑
app.get('/getfile', async (req, res) => {
  const key = req.query.key;
  try {
    await readFile(res, key);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

2. 前端代码调整(可选)

如果后端直接返回二进制PDF,你当前的前端代码(使用arraybuffer或blob作为responseType)已经可以正常工作。也可以简化为:

// Angular服务部分
getObj(key: string): Observable<Blob>{
  return this.http.get(environment.s3Ep + '/getfile?key=' + key, {
    responseType: 'blob'
  });
}

// 调用部分
this.s3Svc.getObj(key).subscribe(
  res => {
    const fileURL = URL.createObjectURL(res);
    window.open(fileURL);
  } 
);

内容的提问来源于stack exchange,提问作者elesh.j

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 06:50:27