How to enable CORS by post binary file into API Gateway

api-gateway
#1

I have a problem with cors policy in my application. I would like to upload an image file to my Lambda that saves the file into AWS s3.

I don’t win a fight with CORS. After fetch from a client I have next errors in my console. I really don’t have any ideas to resolve this problem. All code works fine if I send a POST request from Insomnia/PostMan.

Can anybody help me?

OPTIONS https://....execute-api.eu-central-1.amazonaws.com/... 500

Access to fetch at 'https://....execute-api.eu-central-1.amazonaws.com/...' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

There are my code samples

serverless.yaml

service: save-user-file

frameworkVersion: ">=1.1.0"

custom:
  bucket: <bucket-name>

provider:
  name: aws
  runtime: nodejs8.10
  stage: dev
  region: eu-central-1
  apiGateway:
    binaryMediaTypes: # Optional binary media types the API might return
      - '*/*'
  iamRoleStatements:
    - Effect: Allow
      Action:
        - s3:PutObject
        - s3:PutObjectAcl
      Resource:
        - "arn:aws:s3:::${self:custom.bucket}/*"

functions:
  save:
    handler: handler.save
    environment:
      BUCKET: ${self:custom.bucket}
    events:
      - http:
          path: files
          method: post
          cors: true

hendler.save

const uuid = require('uuid');
const AWS = require('aws-sdk');

const s3 = new AWS.S3();
const s3PublicUrl = 'https://s3.eu-central-1.amazonaws.com/bucket-name/';

module.exports.save = (event, context, callback) => {
  const id = uuid.v1();

  const buffer = new Buffer(event.body, 'base64');
  const fileType = 'jpg';
  const fileKey = `${id}.${fileType}`;

  const s3Params = {
    Bucket: process.env.BUCKET,
    Key: fileKey,
    Body: buffer
  };

  s3.putObject(s3Params, error => {
    if (error) {
      console.error(error);
      callback(null, {
        statusCode: error.statusCode || 501,
        headers: {
          'Content-Type': 'application/json',
          'Access-Control-Allow-Origin': '*',
        },
        body: JSON.stringify({ error: "Couldn't create the image item s3." })
      });
      return;
    }

    const response = {
      statusCode: 200,
      body: JSON.stringify({ display_url: `${s3PublicUrl}${fileKey}` }),
      headers: {
        'Content-Type': 'application/json',
        'Access-Control-Allow-Origin': '*',
      }
    };
    callback(null, response);
  });
};

fetch request from client

fetch('https://...execute-api.eu-central-1.amazonaws.com/...', {
    method: 'POST',
    body: file,
    mode: 'cors',
    headers: {
      'Content-Type': 'image/jpeg',
    }
  })
    .then(res => {
      res.json();
    })
    .then(res => {
      console.log(res);
      put(actions.successPublishUserFile());
    })
    .catch(error => {
      put(actions.errorPublishUserFile(error));
    });

Thanks!
Maxim