Jquery AWS Lambda将文件上载到s3

Jquery AWS Lambda将文件上载到s3,jquery,amazon-s3,multipartform-data,boto3,chalice,Jquery,Amazon S3,Multipartform Data,Boto3,Chalice,我有一个AWS lambda函数,它接收多部分表单数据,将其解析为文档(可以是.pdf、.doc或.docx),然后将其上传到S3存储桶。我正在接收表单数据,对其进行解析,并似乎很好地上传了它。但是,当我去下载文件时,如果是.doc或.docx,它就无法打开,如果是.pdf,它只是一个空白页。从本质上讲,这些文件在流程管道中的某个位置被损坏。在这一点上,我真的不知道我做错了什么。数据传输步骤如下所示: 表单上传到客户端,base64编码在FormDataobject(JS)中 表单通过jQuer

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

  • 表单上传到客户端,base64编码在
    FormData
    object(JS)中
  • 表单通过jQueryAjax发送
  • 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);
        }
    });
    
  • 相应的pythonapi(内置)路由处理它
  • 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。尽管如此,我仍然对是否有办法使用
    多部分/表单数据
    感兴趣