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

如何将PDF从服务器直传至浏览器?解决AWS多EC2实例文件访问问题

解决方案

1. 直接流式传输PDF到浏览器(无需本地存储)

跳过本地文件写入步骤,直接将第三方返回的Base64格式PDF解码后作为HTTP响应发送给浏览器,彻底避免本地存储带来的跨实例问题。

修改后的代码示例(以Express路由为例):

app.get('/download-pdf/:id', async (req, res) => {
  try {
    const { id } = req.params;
    const pdfData = await someThirdParty(id);

    if (!pdfData.data.data.success) {
      throw new Error(pdfData.data.data.message);
    }

    // 移除Base64前缀并解码为Buffer
    const base64Pdf = pdfData.data.data.report.replace(/^data:application\/pdf;base64,/, '');
    const pdfBuffer = Buffer.from(base64Pdf, 'base64');

    // 设置响应头,告知浏览器这是可下载的PDF文件
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', 'attachment; filename="report.pdf"');
    res.setHeader('Content-Length', pdfBuffer.length);

    // 直接将Buffer发送给浏览器
    res.send(pdfBuffer);
  } catch (err) {
    res.status(500).send(`下载失败: ${err.message}`);
  }
});

如果第三方服务支持返回二进制流,可进一步优化为流式传输(避免全量加载到内存):

const axios = require('axios');

app.get('/download-pdf/:id', async (req, res) => {
  try {
    const { id } = req.params;
    // 配置请求直接获取二进制流
    const response = await axios.get(`第三方服务PDF接口/${id}`, {
      responseType: 'stream'
    });

    if (!response.data.success) {
      throw new Error(response.data.message);
    }

    // 设置响应头
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', 'attachment; filename="report.pdf"');

    // 将第三方返回的流直接管道到响应流
    response.data.pipe(res);
  } catch (err) {
    res.status(500).send(`下载失败: ${err.message}`);
  }
});

2. 无服务器化改造(替换EC2集群)

要构建无服务器高效系统,推荐用AWS Lambda + API Gateway替代EC2:

  • 用Lambda函数处理PDF请求逻辑(复用上面的流式传输代码)
  • 通过API Gateway暴露HTTP端点,用户直接请求该端点
  • 无需维护EC2实例,也不用配置粘性会话,Lambda自动按需扩缩容

Lambda适配代码(Node.js运行时):

const axios = require('axios');

exports.handler = async (event) => {
  try {
    const id = event.pathParameters.id;
    const pdfData = await someThirdParty(id);

    if (!pdfData.data.data.success) {
      throw new Error(pdfData.data.data.message);
    }

    const base64Pdf = pdfData.data.data.report.replace(/^data:application\/pdf;base64,/, '');
    
    return {
      statusCode: 200,
      headers: {
        'Content-Type': 'application/pdf',
        'Content-Disposition': 'attachment; filename="report.pdf"'
      },
      body: base64Pdf,
      isBase64Encoded: true
    };
  } catch (err) {
    return {
      statusCode: 500,
      body: JSON.stringify({ error: `下载失败: ${err.message}` })
    };
  }
};

// 第三方服务请求封装
async function someThirdParty(id) {
  return axios.get(`第三方服务的PDF接口/${id}`);
}

核心优势

  • 彻底摆脱粘性会话依赖:每个请求独立处理,无需绑定特定实例
  • 自动扩缩容:流量高峰时Lambda自动扩容,低峰时缩容,降低成本
  • 零本地存储:数据全程在请求链路中传输,不落地任何服务器磁盘

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 18:42:41