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

借助AWS Lambda函数向Box上传文件——多部分解析问题

问题分析与修复方案

你的Lambda函数上传文件到Box后损坏,核心问题出在multipart/form-data解析逻辑错误以及二进制数据处理不当,具体问题点和修复方式如下:

核心问题

  1. 未处理Base64编码的请求体:API Gateway触发Lambda时,multipart/form-data的请求体默认是Base64编码的,直接将event['body']当作字符串处理会破坏二进制文件数据。
  2. 手动提取boundary不可靠:通过data.split("\r")[0][2:]获取boundary的方式容易出错,应该从content-type头中规范提取。
  3. 二进制数据错误编码:将part.value用latin-1编码写入文件,会改变原始二进制内容,导致文件损坏。

修复后的代码

import os
import json
import boto3
import uuid
import urllib3
import base64
from io import BytesIO
from multipart import MultipartParser
from email.parser import HeaderParser

ssm = boto3.client('ssm', 'us-east-2')
http = urllib3.PoolManager()

def getToken(token_url):
    # 补充你原本的getToken实现逻辑
    pass

def lambda_handler(event, context):
    content_type = event['headers'].get('content-type', '')
    if content_type.startswith('multipart/form-data'):
        # 1. 从content-type头中规范提取boundary
        parser = HeaderParser()
        headers = parser.parsestr(f'Content-Type: {content_type}')
        boundary = headers.get_param('boundary')
        
        # 2. 处理Base64编码的请求体
        body = event['body']
        if event.get('isBase64Encoded', False):
            body = base64.b64decode(body)
        
        # 3. 正确解析multipart数据
        p = MultipartParser(BytesIO(body), boundary)
        parts = p.parts()
        
        for part in parts:
            print("Key (Name):", part.name)
            if part.name == 'file':
                # 直接获取文件原始二进制数据,跳过不必要的编码转换
                file_data = part.raw
                
                # 可选:临时文件验证(调试用,可删除)
                temp_file_path = '/tmp/temp_file.xlsx'
                with open(temp_file_path, 'wb') as temp_file:
                    temp_file.write(file_data)
                
                # 获取Box令牌并执行上传
                token_url = os.environ['TOKEN_URL']
                access_token = getToken(token_url)
                setFileContent(access_token, file_data, f"{uuid.uuid4()}.xlsx")
        
        print('File uploaded to Box successfully')

def setFileContent(token, file_data, file_name):
    url = "https://upload.box.com/api/2.0/files/content"
    headers = {"Authorization": f"Bearer {token}"}
    attributes = {"name": file_name, "parent": {"id": "124435"}}
    fields = {
        "attributes": json.dumps(attributes),
        'file': (file_name, file_data)
    }
    response = http.request('POST', url, headers=headers, fields=fields)
    print(response.status)

关键修复点说明

  • Base64解码处理:检查isBase64Encoded标志,对请求体进行Base64解码,还原原始二进制数据。
  • 规范提取boundary:使用email.parser.HeaderParser从content-type头中正确提取boundary,避免手动分割的潜在错误。
  • 保留原始二进制:使用part.raw直接获取文件的原始字节数据,跳过字符串编码转换步骤,确保文件内容完整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 03:23:34