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

使用API Gateway和Lambda上传文件至S3时遇ASCII字符错误求助

问题:API Gateway+Lambda上传MP3到S3报错:ValueError: string argument should contain only ASCII characters

尝试使用API Gateway和Lambda将文件上传至S3,Lambda环节前流程均正常运行,Lambda代码如下:

import base64
import boto3
import os

s3_client = boto3.client('s3')
bucket_name = os.environ['S3_BUCKET_NAME']


def lambda_handler(event, context):
    contend_decode = base64.b64decode(event['body'])
    response = s3_client.put_object(Bucket=bucket_name, Body=contend_decode)
    print(response)

    return {
        'statusCode': 200,
        'body': 'File uploaded'
    }

上传MP3文件时收到如下错误:

[ERROR] ValueError: string argument should contain only ASCII characters
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 10, in lambda_handler
    contend_decode = base64.b64decode(event['body'])
  File "/var/lang/lib/python3.8/base64.py", line 80, in b64decode
    s = _bytes_from_decode_data(s)
  File "/var/lang/lib/python3.8/base64.py", line 39, in _bytes_from_decode_data
    raise ValueError('string argument should contain only ASCII characters')
[ERROR] ValueError: string argument should contain only ASCII characters Traceback (most recent call last):   File "/var/task/lambda_function.py", line 10, in lambda_handler     contend_decode = base64.b64decode(event['body'])   File "/var/lang/lib/python3.8/base64.py", line 80, in b64decode     s = _bytes_from_decode_data(s)   File "/var/lang/lib/python3.8/base64.py", line 39, in _bytes_from_decode_data     raise ValueError('string argument should contain only ASCII characters')

编辑补充:事件内容示例

{
    "resource": "/upload",
    "path": "/upload",
    "httpMethod": "POST",
    "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate, br",
        "CloudFront-Forwarded-Proto": "https",
        "CloudFront-Is-Desktop-Viewer": "true",
        "CloudFront-Is-Mobile-Viewer": "false",
        "CloudFront-Is-SmartTV-Viewer": "false",
        "CloudFront-Is-Tablet-Viewer": "false",
        "CloudFront-Viewer-ASN": "5410",
        "CloudFront-Viewer-Country": "FR",
        "Content-Type": "audio/mpeg",
        "Host": "um8xxxxpxx.execute-api.eu-west-1.amazonaws.com",
        "Postman-Token": "fe49e15f-82c6-44c7-8399-4b6fba9b9abc",
        "User-Agent": "PostmanRuntime/7.29.2",
        "Via": "1.1 12bc6711250373a4xxxxxxxxxx44504.cloudfront.net (CloudFront)",
        "X-Amz-Cf-Id": "5Zv2MVCxxxxxxxxxxxxyzMuv_CfIAxxxxxxxxxxxxJyz4JtHb-QImYZGQ==",
        "X-Amzn-Trace-Id": "Root=1-6383d306-4e81300e0000000c3262b7a45",
        "x-api-key": "g4KOPDl5zoB0E2QBpAAXSaESDFyGkR38f000",
        "X-Forwarded-For": "1XX.XX9.2XX.XX9, 1XX.XX6.XX5.XXX",
        "X-Forwarded-Port": "443",
        "X-Forwarded-Proto": "https"
    },
    "multiValueHeaders": {
        "Accept": [
            "*/*"
        ],
        "Accept-Encoding": [
            "gzip, deflate, br"
        ],
        "CloudFront-Forwarded-Proto": [
            "https"
        ],
        "CloudFront-Is-Desktop-Viewer": [
            "true"
        ],
        "CloudFront-Is-Mobile-Viewer": [
            "false"
        ],
        "CloudFront-Is-SmartTV-Viewer": [
            "false"
        ],
        "CloudFront-Is-Tablet-Viewer": [
            "false"
        ],
        "CloudFront-Viewer-ASN": [
            "5410"
        ],
        "CloudFront-Viewer-Country": [
            "FR"
        ],
        "Content-Type": [
            "audio/mpeg"
        ],
        "Host": [
            "um8xxxxpxx.execute-api.eu-west-1.amazonaws.com"
        ],
        "Postman-Token": [
            "fDDDDf-82c8-44c9-DDD1-4b6f9QASFF9abc"
        ],
        "User-Agent": [
            "PostmanRuntime/7.29.2"
        ],
        "Via": [
            "1.1 12bVASD16aeca2DDD44504.cloudfront.net (CloudFront)"
        ],
        "X-Amz-Cf-Id": [
            "5Zv2MVCnaDDDzMuv_CfIA6iC89CiUnjDDDAZXAb-QImYZGQ=="
        ],
        "X-Amzn-Trace-Id": [
            "Root=1-6383AZDD-4e81002e022374c326hu8a45"
        ],
        "x-api-key": [
            "g4KOPDl5zoBia3cT4pYMkynzyGkX00aa"
        ],
        "X-Forwarded-For": [
            "1XX.XX9.2XX.XX9, 1XX.XX6.XX5.XXX"
        ],
        "X-Forwarded-Port": [
            "443"
        ],
        "X-Forwarded-Proto": [
            "https"
        ]
    },
    "queryStringParameters": "None",
    "multiValueQueryStringParameters": "None",
    "pathParameters": "None",
    "stageVariables": "None",
    "requestContext": {
        "resourceId": "adddazq",
        "resourcePath": "/upload",
        "httpMethod": "POST",
        "extendedRequestId": "cR3o-zddEFgazz=",
        "requestTime": "27/Nov/2022:21:13:42 +0000",
        "path": "/dev/upload",
        "accountId": "114782879802",
        "protocol": "HTTP/1.1",
        "stage": "dev",
        "domainPrefix": "ua8xjwxraf",
        "requestTimeEpoch": 1669583622098,
        "requestId": "23e099f9-eda4-42b2-8b4f-b1aaea589978",
        "identity": {
            "cognitoIdentityPoolId": "None",
            "cognitoIdentityId": "None",
            "apiKey": "h4KOPDl5zoqsdT4pYMkynzdddaz8f95560",
            "principalOrgId": "None",
            "cognitoAuthenticationType": "None",
            "userArn": "None",
            "apiKeyId": "z887qsddox4",
            "userAgent": "PostmanRuntime/7.29.2",
            "accountId": "None",
            "caller": "None",
            "sourceIp": "176.139.21.129",
            "accessKey": "None",
            "cognitoAuthenticationProvider": "None",
            "user": "None"
        },
        "domainName": "um8xxxxpxx.execute-api.eu-west-1.amazonaws.com",
        "apiId": "um8xxxxpxx"
    },
    "body": "\x04\x08-P�\x10,Gh�m\x0c\x06K����Te�U�-��\r\x01�Y��l�,3�\x11�Q�4$�........6��\x1872Ip�d�p\x1d�M�PX�0`�x�0����d�\x0f�\x0c.ǃ��\x12\x00\x00\r \x00\x00\x01\x18��........",
    "isBase64Encoded": "False"
}

注:仅展示了body中的部分字符用于演示。


解决方案

问题原因

API Gateway收到二进制MP3请求时,未将其编码为base64格式,而是直接以原始二进制字符的形式传递给Lambda。从事件中的isBase64Encoded: "False"可以确认这一点。此时event['body']包含大量非ASCII字符,而base64.b64decode仅能处理ASCII格式的base64字符串,因此触发报错。

修复方式(二选一即可)

方式一:修改API Gateway配置,开启二进制请求的base64编码

  1. 进入AWS控制台的API Gateway服务,找到对应的API
  2. 切换到设置(Settings)页面,在Binary Media Types中添加audio/mpeg(如果需要支持所有二进制类型,可添加*/*)
  3. 重新部署API到对应阶段

方式二:修改Lambda代码,直接处理原始二进制内容

无需对event['body']进行base64解码,直接将字符串转换为字节即可,因为latin-1编码可准确映射每个字符到对应的字节,不会丢失原始数据:

import boto3
import os

s3_client = boto3.client('s3')
bucket_name = os.environ['S3_BUCKET_NAME']


def lambda_handler(event, context):
    # 将原始body字符串转为字节
    file_content = event['body'].encode('latin-1')
    response = s3_client.put_object(Bucket=bucket_name, Body=file_content)
    print(response)

    return {
        'statusCode': 200,
        'body': 'File uploaded'
    }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 01:25:26