Access to XMLHttpRequest at 'https://...' from origin 'https://...' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I'm using API Gateway with an AWS_PROXY integration for my Lambda function. I have also configured S3 Bucket Policies to allow s3:GetObject. Below is my configuration:
API Gateway Configuration This includes an OPTIONS method to enable CORS.
MatasApiMethod:
Type: AWS::ApiGateway::Method
Properties:
HttpMethod: ANY
ResourceId: !Ref MatasApiResourceProxy
RestApiId: !Ref StaticWebsiteApi
AuthorizationType: NONE
RequestParameters:
method.request.path.proxy: true
Integration:
Type: AWS_PROXY
IntegrationHttpMethod: POST
Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MatasLambdaFunction.Arn}/invocations
MatasApiOptionsMethod:
Type: AWS::ApiGateway::Method
Properties:
HttpMethod: OPTIONS
ResourceId: !Ref MatasApiResourceProxy
RestApiId: !Ref StaticWebsiteApi
AuthorizationType: NONE
Integration:
Type: MOCK
RequestTemplates:
application/json: '{"statusCode": 200}'
IntegrationResponses:
- StatusCode: 200
ResponseParameters:
method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
method.response.header.Access-Control-Allow-Methods: "'OPTIONS,GET,POST,PATCH,PUT,DELETE'"
method.response.header.Access-Control-Allow-Origin: "'*'"
ResponseTemplates:
application/json: "{}"
MethodResponses:
- StatusCode: 200
ResponseParameters:
method.response.header.Access-Control-Allow-Headers: true
method.response.header.Access-Control-Allow-Methods: true
method.response.header.Access-Control-Allow-Origin: true
S3 Bucket Configuration
DynamicAssetsBucket:
Type: AWS::S3::Bucket
Properties:
Tags:
- Key: identifier
Value: matas-dynamic
- Key: Environment
Value: Production
DynamicAssetsBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref DynamicAssetsBucket
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
AWS: "arn:aws:iam::712023455730:role/GitHubTestRoleMatas"
Action: "s3:GetObject"
Resource: !Sub "arn:aws:s3:::${DynamicAssetsBucket}/*"
Lambda Code for Uploading to S3
export async function writeFileToS3(
key: string,
objectName: string,
file: UploadedFile,
ext: string
) {
try {
const hashedNameFile = objectHash(`${objectName}`);
const filePath = `assets/${process.env.DB_SCHEMA}/${key.split("Src")[0]}/${hashedNameFile}.${ext}`;
const upload = new Upload({
client: s3Client,
params: {
Bucket: Config.srcBucket,
Key: filePath,
Body: file.data,
ContentEncoding: file.encoding,
ContentType: file.mimetype,
},
queueSize: 4,
leavePartsOnError: false,
});
await upload.done();
return filePath;
} catch (error) {
console.error("Error uploading file", file.name, error);
}
}
What I Have Tried: CORS Configuration in API Gateway
I added an OPTIONS method for handling preflight requests. API Gateway explicitly allows Access-Control-Allow-Origin: '*'. S3 Bucket Policy
The policy allows s3:GetObject, but I suspect I may need to configure CORS in S3 directly. Testing via Postman
The Lambda function successfully uploads files to S3. The file is accessible when manually opened in the browser. However, when the frontend requests the file, it gets blocked by CORS. Questions: Do I need to configure S3 CORS policy separately? Should I modify my API Gateway integration response? Am I missing any headers in my Lambda response that might be affecting CORS?