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

AWS SAM Local本地文件上传时出现UnicodeDecodeError问题求助

AWS SAM Local本地文件上传时出现UnicodeDecodeError问题求助

看起来你遇到的是AWS SAM Local模拟API Gateway时,处理前端multipart文件上传的编码兼容问题——Postman能正常工作但前端不行,核心错误是UnicodeDecodeError,咱们一步步来分析和解决:

问题根源分析

错误提示的0xc4字节是典型的非UTF-8二进制内容(比如图片、压缩包这类文件里很常见),你的代码里有一处关键逻辑触发了这个问题:

body_bytes = base64.b64decode(event['body']) if event.get('isBase64Encoded') else event['body'].encode('utf-8')

当SAM Local模拟API Gateway时,前端上传的二进制body可能没有被正确标记为isBase64Encoded,但event['body']里直接包含了非UTF-8的原始字节内容。这时候你用encode('utf-8')去处理,就会触发编码错误——因为非UTF-8字节无法被安全转成UTF-8字符串再编码。

而Postman能正常工作,是因为它发送的请求格式更符合API Gateway的标准,SAM Local正确标记了isBase64Encoded,你的代码能正确解码base64内容。

修复步骤

1. 修复body二进制数据的处理逻辑

把parse_multipart函数中的body_bytes获取逻辑替换为以下代码,用latin-1编码处理非base64的情况——latin-1是单字节编码,能完整保留原始字节内容,不会出现编码错误:

# 修复后的body_bytes处理逻辑
import base64

body_bytes = base64.b64decode(event['body']) if event.get('isBase64Encoded') else event['body'].encode('latin-1')

2. 配置SAM Local的API Gateway二进制媒体类型

确保你的SAM模板(template.yaml)中,API Gateway资源配置了支持multipart/form-data的二进制媒体类型,让SAM Local正确识别并处理二进制请求:

Resources:
  # 替换成你实际的API资源名称
  YourServerlessApi:
    Type: AWS::Serverless::Api
    Properties:
      # 保留你原有其他配置...
      BinaryMediaTypes:
        - multipart/form-data
        - application/octet-stream # 可选,覆盖通用二进制类型

3. 重启SAM Local服务

修改模板后,需要重启SAM Local的API服务,确保配置生效:

sam local stop
sam local start-api

额外优化建议

为了让你的parse_multipart函数更健壮,还可以优化文件名解析逻辑,支持非英文字符的文件名(符合RFC 5987标准的编码格式),替换原有的filename解析代码:

# 优化后的文件名解析逻辑
from email.header import decode_header

if b"filename=" in disposition:
    filename = None
    # 先处理RFC 5987标准的filename*编码格式
    if b"filename*=" in disposition:
        for part in disposition.split(b';'):
            part = part.strip()
            if part.startswith(b'filename*='):
                encoded_filename = part.split(b'filename*=')[1].decode()
                charset, _, fname = encoded_filename.partition("''")
                try:
                    filename = fname.encode('latin-1').decode(charset)
                except (UnicodeDecodeError, LookupError):
                    filename = fname
                break
    # 若filename*不存在,再用原逻辑兼容旧格式
    if not filename:
        try:
            filename = disposition.split(b'filename=')[1].strip(b'"').decode("utf-8")
        except UnicodeDecodeError:
            filename = disposition.split(b'filename=')[1].strip(b'"').decode("utf-8", "replace")

测试验证

完成以上修改后,重新用前端上传文件到SAM Local的API,应该就能避免UnicodeDecodeError,和Postman一样正常处理文件上传了。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 08:02:59