2
votes

I'm trying to use browser canvas to manipulate images I have hosted on cloudfront. I'm trying to setup cloudfront to have the browser cache images with cache control max-age and still allow canvas to edit those images.

Here's an image that I can edit:

https://d2t4fc8ff77neh.cloudfront.net/cardSrcImage/1ac01l796_16dbmg07t_books2.jpg

Here's one that I can't (Image from origin 'https://d2t4fc8ff77neh.cloudfront.net' has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://localhost' is therefore not allowed access.):

https://d2t4fc8ff77neh.cloudfront.net/cardSrcImage/1ac01o3l0_16dbmg07t_books2.jpg

The only thing different is the cache-controls header. What's wrong? Thanks.

I'm using the node.js knox library to upload. Example headers:

var headers = {
  'Content-Length': options.data.length,
  'Vary': 'Accept-Encoding',
  // 'Cache-Control': 'public, max-age=31536000',
  'x-amz-acl': 'public-read',
  'Content-Type': options.type
}
1
To address the "...therefore not allowed access" error, you might try adding 'Access-Control-Allow-Origin': '*' to your headers object; this allows CORS for everyone, but could at least rule out that issue. - Castaglia
@Castaglia I added that but still has the same problem. I thought the x-amz-acl public read was the amazon equivalent? - Harry

1 Answers

1
votes

Okay, I assume you want to just load the images and don't want to save(POST) them back to the same URI. And this works!

Here is a jsbin that works for both images. Here is the code:

var img1 = new Image();
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');


//drawing of the test image - img1
img1.onload = function () {
  ctx.drawImage(img1, 0, 0);
};

//img1.src = 'https://d2t4fc8ff77neh.cloudfront.net/cardSrcImage/1ac01l796_16dbmg07t_books2.jpg';
img1.src = 'https://d2t4fc8ff77neh.cloudfront.net/cardSrcImage/1ac01o3l0_16dbmg07t_books2.jpg';

And the canvas in the html:

<canvas id="canvas" width="1000" height="1000"></canvas>

So your problem is probably how you load the images, but you haven't showed us your code for that.

The caching/cross-origin Problem

Your Problem is that the <img> tag and the Javascript Image have a very different behavior. You can include images from all over the internet with an <img> tag without any origin check, but for the Javascript Image you the same origin policy is active.

In your original HTML you have <img> Tags for your image. This makes your browser fetch the images without an Origin header. This results in your Server not sending the CORS Headers.

Later when you use the Javascript Image your browser has a cached version without the CORS headers and will respond with that. So the request will fail!

Sometimes it looked like chrome is intelligent enough to make an additional request, but this is definitely not ideal.

Now it should be easy to fix this. Maybe first use the Image and later the <img> tag, or just don't use an <img> tag at all. You also could always sent CORS Headers for *, even when no Origin Header is present.


You also have a strange Problem in your resizing function, but I think this is content for a new question if you can't resolve it yourself.