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

通过AWS Lambda与API Gateway上传PDF/docx至S3遇乱码问题求助

这个问题我之前处理过!核心原因是API Gateway默认会把二进制类型的请求体(比如PDF、docx)转成Base64编码,而你现在的代码直接读取了这个Base64字符串,既导致日志显示乱码,也把编码后的内容传到了S3,自然无法正常打开。普通文本文件因为本身是可打印字符,Base64编码后看起来还是正常文本,所以没暴露问题。

解决步骤

1. 配置API Gateway支持二进制媒体类型

首先得让API Gateway知道哪些类型的请求是二进制数据,确保它能正确处理转码:

  • 打开AWS控制台的API Gateway服务,找到你的目标API
  • 切换到「Settings」标签页,在「Binary Media Types」区域点击「Add binary media type」
  • 可以添加具体的MIME类型,比如:
    • application/pdf(针对PDF文件)
    • application/vnd.openxmlformats-officedocument.wordprocessingml.document(针对docx文件)
    • 或者直接加*/*匹配所有类型(适合测试场景,生产环境建议指定具体类型)
  • 重要提醒:配置完后必须点击API顶部的「Deploy API」,选择你的部署阶段(比如prod),否则配置不会生效!

2. 修改Lambda代码处理Base64编码的请求体

API Gateway会把二进制请求的Body转成Base64字符串,同时在请求事件里标记isBase64Encoded=true。你需要在代码里判断这个标记,解码后再上传到S3:

下面是适配你场景的Java代码示例(从你的日志代码来看,你用的是Java Lambda对吧?):

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.PutObjectRequest;
import java.io.ByteArrayInputStream;
import java.util.Base64;

public class S3UploadHandler {
    // 替换成你的目标S3桶名
    private static final String S3_BUCKET = "your-target-bucket";
    private final AmazonS3 s3Client = AmazonS3ClientBuilder.defaultClient();

    public String handleRequest(APIGatewayProxyRequestEvent event, Context context) {
        try {
            // 从请求头提取文件名(Content-Disposition格式类似:form-data; name="file"; filename="test.pdf")
            String contentDisposition = event.getHeaders().getOrDefault("Content-Disposition", "");
            String fileName = contentDisposition.split("filename=")[1].replaceAll("\"", "");

            // 处理请求体:如果是Base64编码则解码,否则直接转字节
            byte[] fileContent;
            if (event.isBase64Encoded()) {
                fileContent = Base64.getDecoder().decode(event.getBody());
            } else {
                fileContent = event.getBody().getBytes();
            }

            // 上传到S3
            s3Client.putObject(
                new PutObjectRequest(S3_BUCKET, fileName, new ByteArrayInputStream(fileContent), null)
            );

            context.getLogger().log("Successfully uploaded file: " + fileName + " (size: " + fileContent.length + " bytes)");
            return String.format("File %s uploaded successfully", fileName);
        } catch (Exception e) {
            context.getLogger().log("Upload failed: " + e.getMessage());
            return "Upload error: " + e.getMessage();
        }
    }
}

3. 关于日志乱码的说明

二进制文件(比如PDF)的原始字节本身就包含很多不可打印的ASCII字符,即使API Gateway不转Base64,直接打印这些字节也会显示乱码。所以日志里看到乱码是正常的,不用纠结——只要最终上传到S3的文件能正常打开,就说明处理正确。如果需要在日志里确认上传状态,打印文件名、文件大小这类元数据就足够了。

测试的时候,上传PDF后可以去S3控制台下载文件,打开看看是否正常。如果还是有问题,先检查API Gateway的部署是否生效,再确认Lambda代码里的Base64解码逻辑是否正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 07:22:45