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

Lambda PDF代理函数运行超时、无法返回Base64编码PDF问题求助

Lambda函数抓取PDF问题排查

目标

传入HTTP请求参数抓取PDF文件,并通过Lambda服务将文件转发给请求方。

当前代码

"use strict";
const http = require("http");

function getPDF(options, event) {
   console.log(options);
  return new Promise((resolve, reject) => {
    let body = "";
    let statusCode = 0;
    let headers = { };
    
    http
      .request(options, (res) => {
        statusCode = res.statusCode;
        const headersFromReq = res.headers || {};

        res.on("data", (chunk) => (body += chunk));

        res.on("end", function () {
          console.log( statusCode, headers, body);
          resolve({ 
            body: Buffer.from(body).toString(),
            statusCode, 
          headers: {
            ...headersFromReq, 
            //'Content-type': 'application/pdf',
            //'content-disposition': 'attachment; filename=test.pdf'
          }
        });
      })
      .on("error", reject)
      .end();
  });
});
}

exports.handler = async (event) => {
  try {
    const response = await getPDF(event.options, event);
    return response;
  } catch (error) {
    console.error(error);
    return {
      statusCode: 500,
      body: JSON.stringify(error),
      headers: {}
    };
  }
};

问题现象

无论如何调试,该函数要么触发超时,要么无法返回预期的Base64编码PDF结果。

测试参数示例

{
  "options": {
    "hostname": "www.africau.edu",
    "port": 80,
    "path": "images/default/sample.pdf",
    "method": "GET",
    "headers": {
      "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36",
      "Accept": "application/pdf",
      "Accept-encoding": "gzip, deflate, br"
    }
  }
}

当前运行日志

Function Logs
START RequestId: 8d6be86c-788d-4f49-8305-8caf377cd32e Version: $LATEST
2021-09-28T09:01:21.507Z    8d6be86c-788d-4f49-8305-8caf377cd32e    INFO    {
  hostname: 'www.africau.edu',
  port: 80,
  path: 'images/default/sample.pdf',
  method: 'GET',
  headers: {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36',
    Accept: 'application/pdf',
    'Accept-encoding': 'gzip, deflate, br'
  }
}
END RequestId: 8d6be86c-788d-4f49-8305-8caf377cd32e
REPORT RequestId: 8d6be86c-788d-4f49-8305-8caf377cd32e  Duration: 11011.54 ms   Billed Duration: 11000 ms   Memory Size: 128 MB Max Memory Used: 54 MB  Init Duration: 152.43 ms    
2021-09-28T09:01:32.494Z 8d6be86c-788d-4f49-8305-8caf377cd32e Task timed out after 11.01 seconds

问题排查结果

1. 超时原因

  • 错误的事件绑定位置:当前代码将error事件绑定到了响应对象res上,而非http.request返回的请求对象,请求阶段出现的网络错误、DNS解析失败等问题无法被捕获,会导致Promise一直处于pending状态,直到Lambda超时。
  • 请求路径错误:测试参数中的path字段缺少前导斜杠,正确写法应为/images/default/sample.pdf,路径格式错误会导致目标服务器无法正确响应请求。
  • 压缩编码未处理:请求头中声明接受gzip、deflate、br压缩格式,但原生http模块不会自动处理压缩响应,会导致内容接收异常。

2. 无法返回正确PDF的原因

  • 二进制内容处理错误:PDF是二进制文件,代码中用字符串body += chunk拼接二进制数据会直接损坏文件内容。
  • 缺少Base64编码配置:Lambda返回二进制文件需要将body转成Base64编码,同时添加isBase64Encoded: true的配置字段,否则前端会收到乱码内容。

修复后代码

"use strict";
const http = require("http");
const zlib = require("zlib");

function getPDF(options, event) {
  console.log(options);
  return new Promise((resolve, reject) => {
    // 统一用Buffer存储二进制内容,避免字符串拼接损坏数据
    const chunks = [];
    let statusCode = 0;

    const req = http.request(options, (res) => {
      statusCode = res.statusCode;
      const headersFromReq = res.headers || {};
      
      // 自动处理压缩响应
      let stream = res;
      const contentEncoding = headersFromReq['content-encoding'];
      if (contentEncoding === 'gzip') {
        stream = res.pipe(zlib.createGunzip());
      } else if (contentEncoding === 'deflate') {
        stream = res.pipe(zlib.createInflate());
      } else if (contentEncoding === 'br') {
        stream = res.pipe(zlib.createBrotliDecompress());
      }

      stream.on("data", (chunk) => chunks.push(chunk));
      stream.on("end", function () {
        const buffer = Buffer.concat(chunks);
        resolve({
          // 转Base64编码,标记为Base64格式
          isBase64Encoded: true,
          body: buffer.toString('base64'),
          statusCode,
          headers: {
            ...headersFromReq,
            'Content-type': 'application/pdf',
            'content-disposition': 'attachment; filename=test.pdf'
          }
        });
      });

      stream.on("error", reject);
    });

    // 请求对象绑定错误事件,捕获请求阶段异常
    req.on("error", reject);
    req.end();
  });
}

exports.handler = async (event) => {
  try {
    // 自动补全路径前导斜杠,避免参数格式错误
    if (!event.options.path.startsWith('/')) {
      event.options.path = '/' + event.options.path;
    }
    const response = await getPDF(event.options, event);
    return response;
  } catch (error) {
    console.error(error);
    return {
      statusCode: 500,
      body: JSON.stringify({msg: '请求失败', error: error.message}),
      headers: {}
    };
  }
};

测试参数修改建议

将options.path修改为/images/default/sample.pdf即可正常请求测试用的PDF文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 08:54:03