Get Error event for img that has loaded
I have a function that is waiting on a load or error event for an img tag. Sometimes, I get an error event, and the img tag has naturalWidth and naturalHeight both equal to zero. The odd thing is that looking at the network tab in chrome's developer tools, the status code for the image request was a 302, and the redirected request returned fine with a 200 status. (The actual image is stored on S3, but our server redirects there).
In addition in question actually displays, but not properly because I use naturalWidth and naturalHeight to compute some CSS properties for the image.
I also got an error saying "Cross-origin image load denied by Cross-Origin Resource Sharing policy." I'm not sure if that is related, or if it is even referring to the same image.
I am especially confused because it only ever happens for the first image in a series, and only happens sometimes.
Does anyone know what is going on, or at least how to figure out what is causing the error event?
The S3 bucket and server redirect are both configured to support CORS. However, it appears that whenever this happens, the browser is using a cached image that doesn't have the Access-Control-Allow-Origin header. I believe that what is happening is that earlier in the application we request an image without using CORS, and therefore don't have the headers, then at this point we use CORS, but we hit a cached version that wasn't retrieved with CORS. I still don't know how to resolve this problem though. And I am not 100% sure that that is what is happening, although I am pretty sure it has something to do with caching and cross-origin requests.
I'm also still confused about why I am getting both the error and load events for the same img tag, and the image actually displays. Also, even though the load event handler is called, this.complete is false and this.naturalWidth and this.naturalHeight are zero.
CORS is a technology for allowing websites to issue requests to another separate domain. In your case this is from your web server to the amazon S3 server. You'll need to allow requests from your domain to get through to your S3 resources.
I believe you'll find the information you need here: http://aws.typepad.com/aws/2012/08/amazon-s3-cross-origin-resource-sharing.html
Hope it helps!
From the W3C spec of HTTP response codes:
10.3.3 302 Found
The requested resource resides temporarily under a different URI. Since the redirection might be altered on occasion, the client SHOULD continue to use the Request-URI for future requests. This response is only cacheable if indicated by a Cache-Control or Expires header field.
The temporary URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s).
Now, this means that 302 is the redirect but the browser may cache the new URL instead and translate internally your following requests to that. After a timeout, the browser will retry the original URL without internally redirecting the request. So the error appears on more or less random intervals.
This policy considers cross-domain requests dangerous even if you just want to load an image. Here's one of many examples: exploit cross-domain image loading