UPDATE: I'm now seeing a different error message: 'Access-Control-Allow-Origin' header contains multiple values '*, *'
. I haven't changed anything on my end so I think this is a recent change in how the browser (Brave) reports these CORS errors. Nevertheless this new error message is now saying the problem is the multiple values '*, *'. There are lots of questions about this on the internet and the root cause is always that the server is setting the header multiple times in different places. However, I'm unable to identify where this is happening in my case. As I mentioned in the original post below I'm not setting any CORS response headers on the cloudfront distribution (though I tried and it didn't work, as described below). I've checked the CORS config on the s3 bucket and it's this:
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"POST",
"GET",
"PUT",
"DELETE",
"HEAD"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [
"String"
],
"MaxAgeSeconds": 3000
}
]
So the s3 bucket sets the header.
The associated origin-response
lambda was setting this header too, like this:
response.headers['Access-Control-Allow-Origin'] = [
{ key: 'Access-Control-Allow-Origin', value: '*' },
];
I thought this may be the source of the duplication so I commented it out, but the error remained. So the way I'm looking at this is: out of the 3 places that could be setting the header's value (cloudfront distribution, origin s3 bucket, and the lambda for processing image) there's only one place still setting this CORS header, and it's the s3 bucket. Yet the problem is still happening. What other place can/should I look at?
ORIGINAL POST
I keep getting TypeError: Failed to fetch
when using fetch
API to get images from my cloudfront cdn. A sample URL that demonstrates this problem is https://cdn.dev.textras.com/images/6158ac8f8074530013f8dcde/77b4b530-738c-11ec-ae4a-1d90956db63a.jpeg?w=320&q=100&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYxNTFiZTZkMDJkYmM3MDAxNDIzMDhhZiIsImNvdW50cnlDb2RlIjoiTkdBIiwiaWF0IjoxNjQzMjE4ODE2LCJleHAiOjE2NDM0NzgwMTZ9.m2zcZJ0pv-Sj1q7Mz8w9GNoxzLiHBSCf3Yd8qu-YE4s
. If you use that url as the src
for an <img>
tag, the image loads. If you visit the URL in a browser tab, the image loads. If you open dev tools within that same tab and then do a fetch
request to get the image (i.e. same origin), the fetch
request succeeds. If you request the image using postman or curl
from the terminal, the request succeeds. However if you're in a browser tab with a domain different from my cdn (i.e. cross origin), it doesn't load. This seems like a classic CORS problem. This is a snippet from the template that defines the behavior of the cloudfront distribution. I'm only including the part that defines the behavior that affects this particular image:
...
CloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Aliases: !Ref AliasesParam
Comment: !Ref Comment
CacheBehaviors:
- AllowedMethods: "DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT"
CachedMethods: "GET,HEAD,OPTIONS"
Compress: false
PathPattern: 'videos/thumbnails/*'
DefaultTTL: "1814400"
ForwardedValues:
QueryString: true
QueryStringCacheKeys:
- w
- h
- t
- q
- v
LambdaFunctionAssociations:
- EventType: 'viewer-request'
LambdaFunctionARN: !Ref ViewerRequestFunctionVersionArn
- EventType: 'origin-request'
LambdaFunctionARN: !Ref LambdaVideoPathEdgeVersionArn
- EventType: 'origin-response'
LambdaFunctionARN: !Ref OringResponseFunctionVersionArn
MaxTTL: 31536000
MinTTL: 0
SmoothStreaming: false
TargetOriginId: !Ref IdParam
ViewerProtocolPolicy : "redirect-to-https"
# TrustedSigners:
# - String
The template doesn't specify a response header policy, so I tried setting one of the managed CORS policies directly from the cloudfront dashboard. I tried both the SimpleCORS
and CORS-with-preflight-and-SecurityHeadersPolicy
(i.e. the 2 ends of the spectrum for the managed policies), but the problem persisted.
I've also reviewed this list of possible reasons for TypeError
, and I think it can only be due to the response because the requests works except when I'm requesting from a browser tab with a different origin domain.
Any ideas as to what the problem could be? Thanks!