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

无法通过Ajax上传文件至S3,AWS API(Python Lambda)文件参数传递失败求助

解决Ajax上传文件到API Gateway+Lambda失败的问题

看起来你遇到的核心问题是普通POST参数能正常传递,但FormData文件无法通过API Gateway到达Lambda,我帮你从前端代码、API Gateway配置、Lambda处理三个核心环节逐一排查解决:

一、先修正前端代码的关键错误

你当前的Ajax代码里有个拼写错误,这很可能是导致文件无法传递的直接原因:

  • processType: false 应该改为 processData: false
    jQuery的processData参数默认是true,会自动将请求数据转换成字符串,但对于FormData我们需要禁用这个行为,否则文件数据会被破坏。

修正后的完整Ajax代码可以加上错误回调方便排查:

var fd = new FormData(); 
fd.append("file", file_input.files[0]);
$.ajax({ 
    url: "https://xxxxxxxxxxxxxx.execute-api.ap-xxxx-2.amazonaws.com/xxx/xxx", 
    type: 'POST', 
    data: fd, 
    headers: { "X-API-KEY": apikey}, 
    contentType: false, 
    processData: false, // 修正拼写错误
    cache: false, // 避免缓存干扰
    success: function(data) { 
        if(data['result'] === "true") { 
            $('#issue-error').text('Your report has been submitted successfully.'); 
            $('#issue-error').css('color','green').show(); 
            $('form').find("input[type=text], textarea").val(""); 
        } 
    },
    error: function(xhr, status, error) {
        // 打印错误信息方便调试
        console.log("请求错误:", error);
        console.log("状态码:", status);
        console.log("响应详情:", xhr.responseText);
    }
});

二、配置API Gateway支持文件上传

API Gateway默认对multipart/form-data的处理需要特殊配置,否则会丢失文件数据:

  1. 设置Content Handling为Passthrough

    • 进入API Gateway控制台,找到你的POST方法,点击「Integration Request」
    • 在「Content Handling」下拉菜单选择 Passthrough,不要选「Convert to JSON」(否则会把文件数据转换成错误的JSON格式)
  2. 启用二进制媒体类型支持

    • 如果上传的是二进制文件(图片、PDF等),进入API Gateway的「Settings」页面
    • 在「Binary Media Types」里添加 multipart/form-data(或者具体的文件类型如image/*、application/pdf)
    • 保存后重新部署API(这个步骤很容易忘,不部署配置不会生效)
  3. 确认API Key权限
    虽然你能传递普通参数,但还是建议检查一下API Key关联的Usage Plan是否允许该POST方法的请求,避免权限限制。

三、调整Python Lambda函数处理文件

Lambda接收到的multipart/form-data请求体是Base64编码的,需要解码后用专门的库解析:

  1. 安装依赖库
    你需要使用multipart库来解析表单数据,可以通过Lambda层或者打包代码时包含这个库:

    • 本地执行pip install multipart -t ./,然后把整个目录打包成zip上传到Lambda
  2. 示例Lambda处理代码

import base64
import multipart
from io import BytesIO
import boto3

def lambda_handler(event, context):
    try:
        # 1. 解码Base64格式的请求体
        if event.get('isBase64Encoded', False):
            body = base64.b64decode(event['body'])
        else:
            body = event['body'].encode('utf-8')
        
        # 2. 解析multipart/form-data数据
        content_type = event['headers'].get('Content-Type', event['headers'].get('content-type'))
        form = multipart.MultipartParser(BytesIO(body), content_type)
        
        # 3. 获取上传的文件
        file_part = form.get('file')
        if not file_part:
            return {
                'statusCode': 400,
                'headers': {'Content-Type': 'application/json'},
                'body': '{"result": "false", "error": "未找到上传的文件"}'
            }
        
        # 4. 上传文件到S3
        s3_client = boto3.client('s3')
        s3_client.put_object(
            Bucket='你的S3桶名称',
            Key=file_part.filename,
            Body=file_part.raw
        )
        
        return {
            'statusCode': 200,
            'headers': {'Content-Type': 'application/json'},
            'body': '{"result": "true"}'
        }
    
    except Exception as e:
        return {
            'statusCode': 500,
            'headers': {'Content-Type': 'application/json'},
            'body': f'{{"result": "false", "error": "{str(e)}"}}'
        }
  1. 确认Lambda权限
    确保Lambda的执行角色拥有S3上传权限,添加以下IAM策略(替换为你的桶名称):
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::你的S3桶名称/*"
        }
    ]
}

按以上步骤逐一排查调整后,应该就能成功上传文件到S3了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:02:51