-1

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!

Uche Ozoemena
  • 816
  • 2
  • 10
  • 25

1 Answers1

-1

You might have to enable the OPTIONS method for HTTP requests. This is required after you enable CORS properly. Follow this blog for more details: https://aws.amazon.com/premiumsupport/knowledge-center/no-access-control-allow-origin-error/

Hussain Mansoor
  • 2,934
  • 2
  • 27
  • 40
  • I already do that actually, it's specified in the template file under the `AllowedMethods` property. `OPTIONS` is already there. Any other ideas? PS: i'm not the downvoter of course. My question got downvoted too. – Uche Ozoemena Jan 27 '22 at 09:42
  • I've updated the question with new information so please review and let me know if it gives you any new insights. Thanks! – Uche Ozoemena Jan 27 '22 at 12:09