12

In javascript

const image = new Image() image.crossOrigin = 'Anonymous' image.src = 'https://s3.amazonaws.com/ch-static-beta/avatar/user/1a8fdd22d5ec11e784da0e28350150f71512059569.png'

will get an error of enter image description here

And the http header is enter image description here

But when I use the curl and with this request header, the response will success. like this.enter image description here

xsong
  • 630
  • 1
  • 5
  • 18

2 Answers2

25

That's a caching issue, and a chrome bug*:

*Closed as WONT-FIX, chrome devs said it isn't a bug per se, it's a misconfiguration of the server which should send the allow origin headers to any requests... A related bug report, also closed as WONT-FIX.

You probably already had made a request to this image without requesting for the CORS headers.

When you perform the second request, the browser will wrongly reuse the cached response.

var rand = '?'+Math.random();
var no_cors = new Image();
no_cors.onload = loadCORS;
no_cors.src = 'https://s3.amazonaws.com/ch-static-beta/avatar/user/1a8fdd22d5ec11e784da0e28350150f71512059569.png' + rand;


function loadCORS(){
  var with_cors = new Image();
  with_cors.crossOrigin = 'anonymous';
  with_cors.src = no_cors.src;
  with_cors.onload = function(){console.log('loaded');};
  with_cors.onerror = function(){console.error('failed');};
}

So for a fix: [...] Configure your S3 so that it always sends the cross-origin headers.*
For a workaround, always load the crossOrigin version.
For a temp fix, disable caching.

*It seems it's not possible to setup S3 to do so, see this excellent answer by Michael - sqlbot, which also provides other server-side workarounds.

Kaiido
  • 123,334
  • 13
  • 219
  • 285
  • 1
    As you say, I added a timestamp to the url fixed this issue. Thanks! – xsong Mar 27 '18 at 02:42
  • 1
    @Kalido your diagnosis concurs with mine, at https://serverfault.com/a/856948/153161. This is an issue with S3... it is not currently possible to directly configure it to always return CORS headers, or even `Vary: Origin` for a non-CORS request. – Michael - sqlbot Mar 27 '18 at 10:22
  • @Michael-sqlbot great answer, I am hesitating to create an account just to upvote it, learned a lot since I'm not in the server-side of things. – Kaiido Mar 27 '18 at 11:13
0

I have work on this bug almost 2 years. I thing the problems is related in Amazon servers. I try crossOrigin - no effect. I try to add timestapm query url param - no effect. disable cache or enable cache - no effect. Sometime works, other - no.

Try with chrome edge - not shown image. Try with chrome - image are shown.

And Yes, each of these "workarounds" seems to work for some users. Be sure!!! One day image again will not shown even you did not change/update any of your code/projects.

If you check "disable cache" from inspect. Then after some hours/days/restart everything may work fine. But this is not a fix!!!

the only partial fix is this bad code

image.onerror = function (errorMsg, url, lineNumber, column, errorObj) {
   image.src = "images/notfound.jpg";
    
};
Pit
  • 395
  • 2
  • 11
  • The answer I accepted works for me. In fact, the cause of this issue is before we edit the image, we have loaded the image using ``. this loading does not have `crossOrigin`. after that, we reload the image with `crossOrigin`, the browser use cache. so when you edit the image it will CORS. – xsong Jul 15 '22 at 12:32