Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fetching an image from S3 bucket is not working because of CORS

The problem is i am getting the cors error (response header does not contain Access-Control-Allow-Origin) when i try to fetch using fetch API. Here is my cors config in S3 -

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

The code can be found here - https://codepen.io/sourov0805045/pen/OKVBXM?editors=1111

I have checked the response header and saw it does not contain the Allow-Access-Control-Origin header.

But this works properly if i add this in a <img> tag which is quite puzzling. That time there is no Access-Control-Allow-Origin in the response header as well but the image loads properly.

A have tried the same with axios with no effect.

Please let me know you suggestion on how can i solve this problem.

like image 794
Rasheduzzaman Sourov Avatar asked Jul 21 '19 19:07

Rasheduzzaman Sourov


People also ask

How do I fix a CORS error in AWS?

Cross-Origin Resource Sharing (CORS) errors occur when a server doesn't return the HTTP headers required by the CORS standard. To resolve a CORS error from an API Gateway REST API or HTTP API, you must reconfigure the API to meet the CORS standard.

How do I allow CORS in Fetch?

You can fetch request using mode: 'cors' . In this situation browser will not throw execption for cross domain, but browser will not give response in your javascript function. So in both condition you need to configure cors in your server or you need to use custom proxy server.

How do I handle CORS with html2canvas and AWS S3 images?

You have to either load your image with the crossOrigin attribute set to 'anonymous' directly in your document, or you can try useCORS h2c option. allowTaint option does just say that you don't care if it taints the canvas or not.


1 Answers

First start off by removing un-necessary variables: use cURL from the command line.

Step 1: Issue the pre-flight OPTIONS request:

curl -H "Origin: http://example.com" \
      -H "Access-Control-Request-Method: GET" \
      -H "Access-Control-Request-Headers: X-Requested-With" \
      -X OPTIONS --verbose \
      'https://twisker-s3-files.s3.us-east-2.amazonaws.com/files/-GxfyX_dZ-6313383.jpg'

The response headers you are looking for in the output are:

...
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, POST, PUT, HEAD, DELETE
< Access-Control-Allow-Headers: x-requested-with
< Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
...

Step 2: Issue the GET request:

~ $ curl --head 'https://twisker-s3-files.s3.us-east-2.amazonaws.com/files/-GxfyX_dZ-6313383.jpg' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36' -H 'Referer: https://cdpn.io/boomboom/v2/index.html?editors=1111&key=iFrameKey-a88ea9ee-51a6-0ae2-7350-951a5b1e4e56' -H 'Origin: https://cdpn.io' --compressed

Here is the response:

HTTP/1.1 200 OK
x-amz-id-2: 9D3J5BnHo7YocXQicso+eQAC/PlyoOMpc5QXd+G77HMtWTOd8kYymcJnQ0T8J7tqXetMZgVO8Rw=
x-amz-request-id: 6CE1579D5B039163
Date: Thu, 25 Jul 2019 02:18:41 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, HEAD, DELETE
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
Last-Modified: Wed, 26 Jun 2019 19:18:40 GMT
ETag: "8e26c03714ab4d8e185c29b1c04639f0"
Accept-Ranges: bytes
Content-Type: application/octet-stream
Content-Length: 1573767
Server: AmazonS3

Few things of note:

  1. Access-Control-Allow-Origin and Access-Control-Allow-Methods exist
  2. Their values look to be correct, so CORS should work for you (it did for me on your URL)

https://www.test-cors.org can be used to test CORS requests. It gives some output on each phase of the request.

Last, browsers are very aggressive on caching the pre-flight OPTIONS request. So if you are looking at chrome network debug tools, you may not see the pre-flight OPTIONS request. Sometimes re-starting chrome will clear the OPTIONS cache, sometimes it requires clearing all the browser cache.

This caching can be problematic if you don't have CORS correctly configured server side, and the browser caches the response. Ex: you don't allow GET when you initially configure CORS. You issue the OPTIONS request and the browser caches the response, blocking future GET requests.

like image 104
rynop Avatar answered Oct 12 '22 22:10

rynop