Home  >  Q&A  >  body text

Confused while sending binary image (jpg) data to AWS Lambda backend via AWS API Gateway

Apologies in advance if I missed something simple! I have successfully sent images from React to AWS Lambda via AWS API Gateway. I uploaded it to an s3 bucket in the same Lambda function. The following is the React code:

// 在APP中初始化状态
const [selectedImage, setSelectedImage] = useState();

// 输入
<input
  accept="image/jpg, image/jpeg, image/png"
  type="file"
  onChange={imageChange}
/>
...
...
// 当文件字段更改时触发此函数
const imageChange = (e) => {
    if (e.target.files && e.target.files.length > 0) {
      setSelectedImage(e.target.files[0]);
    }
};
...
...
// 当用户点击接受按钮时触发此函数
async function submitToBackend() {

    // 这里的图像是jpg格式
    setSelectedImage(e.target.files[0]);
   
    const backendResponse = await fetch(awsapigatewayurl, {
      method: "PUT",
      headers: {
        "Content-Type": "image/*",
      },
      body: selectedImage,
    })
    console.log(backendResponse)
}

On the API Gateway, I enabled Lambda proxy forwarding and enabled the binary image format as shown below

Lambda proxy settings

API Gateway Binary Settings

Now here comes the weird part...at least for me.. In my Python backend code I have:

def lambda_handler(event, context):
    key = 'test.jpg'    
    data = event['body']
    decoded_data = base64.b64decode(data)
    image_filelike = io.BytesIO(decoded_data)

    # 创建日期文件夹,如果已经创建则忽略
    current_date = str(datetime.date.today())
    s3_client.put_object(Bucket=BUCKET, Key=(current_date + '/'))

    # 将图像上传到S3
    s3_client.upload_fileobj(Bucket=BUCKET, 
                            Key='%s/%s' % (current_date, key), 
                            Fileobj=image_filelike)

But you see I have to do this:

decoded_data = base64.b64decode(data)

I thought I was crazy, so I went into Postman, copied the curl command, and modified it to send binary data from my command prompt like this:

curl --location --request PUT "apigatewayurl" \
--header "Content-Type: image/jpeg" \
--data-binary "@/Users/user/Documents/IMG_7138.jpg"

It works fine.

I should base64 encode the data but from what I see API Gateway or something in the chain already does that. Please tell me if I'm doing something wrong and if it should be done in a better way.

P粉300541798P粉300541798221 days ago500

reply all(1)I'll reply

  • P粉799885311

    P粉7998853112024-04-06 09:34:30

    Okay, take a look at this articlehttps://aws.amazon.com/blogs/compute/handling-binary-data-using-amazon-api-gateway-http-apis/, It looks like the encoding is determined based on the "content-type" header. You can view the Python backend code by using the following code in a Lambda function and viewing the results in the CloudWatch logs:

    print("isBase64Encoded: %s" % event['isBase64Encoded'])

    I'll keep the code and solution here so others can use it if they need help.

    reply
    0
  • Cancelreply