IT序号网

jquery之AWS Lambda将文件上传到s3

findumars 2025年05月04日 编程语言 106 0

我有一个AWS lambda函数,该函数接受多部分表单数据,将其解析为文档(可以是.pdf,.doc或.docx),然后将其上传到S3存储桶。我正在接收表单数据,对其进行解析,然后似乎将其上传就好了。但是,当我去下载文件时,如果它是.doc或.docx,则无法打开;如果是.pdf,则只是空白页。本质上,文件在流程管道中的某个位置已损坏。在这一点上,我真的不知道我在做什么错。数据传输步骤如下:

  • 表单已上传到客户端,并以FormData对象(JS)
  • 进行base64编码
  • 表单是通过jQuery ajax发送的

  • form.js
    $.ajax({ 
        type: 'POST', 
        processData: false, 
        url: `${API_BASE}/applications`, 
        contentType: false, 
        data: formData, 
        success: (data) => { 
            isFormValid = true; 
            callback(); 
        }, 
        error: (err) => { 
            console.log(err); 
        } 
    }); 
    
  • 相应的Python API(使用Chalice构建)路由将其处理为

  • route.py
    import arrow 
    import boto3 
    import cgi 
    from io import BytesIO 
    from app import app, verify_token 
    from chalice.app import Request 
    from chalicelib.core.constants import aws_credentials 
     
    s3_path: str = 'tmp/' 
    s3_metrics_file: str = 'metrics.json' 
    s3_metrics_key: str = s3_path + s3_metrics_file 
     
    # Just testing different ways to instantiate client 
    s3_client = boto3.client("s3", **aws_credentials) 
    s3_resource_client = boto3.resource("s3", **aws_credentials) 
     
    company_name = 'company' 
     
    def _get_parts(current_request) -> dict: 
        """Parse multipart form data""" 
        raw_file: bytearray = BytesIO(current_request.raw_body) 
        content_type = current_request.headers['content-type'] 
        _, parameters = cgi.parse_header(content_type) 
        parameters['boundary'] = parameters['boundary'].encode('utf-8') 
        parsed: dict = cgi.parse_multipart(raw_file, parameters) 
     
        return parsed 
     
     
    @app.route('/applications', cors=True, content_types=['multipart/form-data'], methods=['POST']) 
    def create_application() -> dict: 
        """Creates an application object, stores it and sends an email with the info""" 
        current_request: Request = app.current_request 
     
        # Resume has to stay as bytes 
        body: dict = {k: v[0].decode() if k != 'resume' else v[0] for (k, v) in _get_parts(current_request).items()} 
        resume: bytes = body.get('resume', None) 
        file_name: str = body.get('file_name') 
        portfolio: str = body.get('portfolio', None) 
        file_name_new: str = f'{first_name}_{last_name}_{arrow.utcnow().format("YYYY-MM-DD")}.{file_name.split(".")[-1]}' 
        file_location: str = f'https://s3.amazonaws.com/{company_name}-resumes/{file_name_new}' if resume else None 
     
        s3_client.put_object(Body=resume, Bucket=company_name, Key=file_name_new) 
        # Different way to do the same thing 
        # s3_resource_client.Bucket('52inc-resumes').put_object(Key='test.jpg', Body=resume) 
    

    客户端或服务器端均未发生任何错误。看来这是一个编码转换问题,从base64到字节再到s3上的文件。我该如何解决这个问题?

    请您参考如下方法:

    我最终通过仅将json与base64字符串一起使用解决了此问题,不再需要multipart/form-data或JavaScript FormData对象。从那里,我可以简单地解析出base64字符串并将其发送到S3。仍然会对是否有一种方法使用multipart/form-data感兴趣。


    评论关闭
    IT序号网

    微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!