7

I'm trying to display images on a canvas. The images are hosted on S3.

CORS is set up on AWS, and the CrossOrigin attribute is set to anonymous in the script.

Everything works fine on Firefox — but images are not being loaded on Chrome and Safari.

Errors Safari:

Origin https://www.example.com is not allowed by Access-Control-Allow-Origin. http://mybucket.s3.amazonaws.com/bubble/foo.PNG

[Error] Failed to load resource: Origin https://www.example.com is not allowed by Access-Control-Allow-Origin. (foo.PNG, line 0)

Cross-origin image load denied by Cross-Origin Resource Sharing policy.

Errors Chrome:

Access to Image at 'https://mybucket.s3.amazonaws.com/bubble/foo.PNG' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

The CORS configuration is pretty standard. I tried <AllowedOrigin>*</AllowedOrigin>, and a couple of other variations, but it didn't make any difference … with one exception: <AllowedOrigin>null</AllowedOrigin> seemed to work for Chrome.

CORS configuration on AWS

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

Canvas Script

let myImage = new Image();
myImage.setAttribute('crossOrigin', 'anonymous');

myImage.src = thisDocument.url;
myImage.onload = function() {
  canvas = document.getElementById('myCanvas');
  context = canvas.getContext('2d');

  canvas.setAttribute('width', 200);
  canvas.setAttribute('height', 200);

  context.fillStyle = hsl(0, 50%, 50%);
  context.fillRect(0, 0, 120, 120);
  context.drawImage(myImage, 12, 12, 60, 60);
};
Kai
  • 417
  • 4
  • 15
  • `origin 'null'` != `http[s]://example.com` from your allowed origins. I'm guessing `origin 'null'` means you're testing as `http://localhost`? – Michael - sqlbot Jan 20 '18 at 07:24
  • Unfortunately that's not the case. :( The app runs on Meteor's Galaxy (Docker/AWS), and the images are hosted on S3. – Kai Jan 22 '18 at 20:00
  • What is the solution to this? Please check https://stackoverflow.com/questions/60024200/chrome-v76-cors-problem-amazon-s3-bucket-and-heroku-django-web-app – Joshua Feb 02 '20 at 08:51

1 Answers1

7

I had a very similar issue to this (using S3 hosting with Access-Control errors on Safari and Chrome).

It ended up being a caching issue specific to Chrome and Safari. If you load an image via CSS or an <img> tag, the image will be cached without the Access-Control-Allow-Origin header.

You can check if this is the case for you by disabling caching and checking if the error persists. If it is the issue this answer will likely help: Refresh image with a new one at the same url

chriselderer
  • 186
  • 1
  • 1
  • 8
  • It looks like you're right. The image had been loading, when the developer window was open, and cache was (inadvertently) disabled. – Kai Feb 08 '18 at 08:36
  • 1
    I have the same problem, but I want to use cache in my site, How we can cache the image with the access-control-allow-origin header? can you please provide some explanation? – Mayur Kukadiya Dec 24 '18 at 03:08
  • I thought I was going mad until I found this answer - the same image is used in in img tag on my page. I fixed this by adding `?canvas=true` to the url using in my javascript, then it is treated as a separate image. – anorakgirl Dec 07 '20 at 10:16