Inconsistent behavior of CORS policy

I thought I was going mad … and may be but I have a 100% repro.

1: Invalidate content on s3 (accessed via cloundfront)
2. Attempt to use texture loader to load content.
This results in a CORS error 100% of the time.

Access to Image at ‘path…/187.jpg’ from origin ‘https://mydomain’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘https://mydomain’ is therefore not allowed access.

  1. Try and load the image as many times as you like - it will not work.

  2. Open the developer console in Chrome. Try and load image again.
    It works. Image loads. 100% of the time.

Here is my code

	var imageTextureLoader = new THREE.TextureLoader();

	testMode ? imageTextureLoader.setCrossOrigin("") : imageTextureLoader.setCrossOrigin("use-credentials"); // confirmed that test mode is FALSE so "use-credentials" is being used. 
	imageTextureLoader.load(imageName, function(imageTexture){... //name and texture don't change at all. 

what am I missing?

So you just want to ensure that it’s not possible to load the texture from your AWS backend from a different domain, even with open developer console? Can you please share a URL to one of your textures?

Correct - and we are using cookies to control access to the content. So we are relying on the stored cookies to be sent along with the request.

We know the cookies are correct because other systems are working. Namely a video player (and we know because if we disable its ability to transmit the cookies then it stops working).

However THREE in the case where the console is closed does not work. And its particularly hard to troubleshoot because the network tab in chrome doesn’t populate unless the console is open so we cant inspect the headers. All we see in the console is messaging about a CORS failure. And we don confirm that before the call to load the property crossOrigin has the correct value.

I can privately send you a link to a texture (how would I do this) but it won’t work for you because you are not on the host and the system is expecting all the right config.

What do you recommend we do to test?

three.js just uses the HTML5 image element to load texture from the backend. And the parameter of .setCrossOrigin() is directly set to the crossorigin attribute.

I suggest you do a little test: Try to load a texture just with the image element and see what happens. I guess it the same behavior like using THREE.TextureLoader or THREE.ImageLoader.

Loading images in an image element works. And by that I mean that if I have an image element and point it to one of my target URLs’ then the image loads just fine. In fact I have a selector that allows the user to choose the image they want to load into three.js and this selector is just a collection of image elements. And I don’t set the crossorigin attribute on the image element. My understanding is that IMG does not care about CORS and I’ve seen a few references to this before such as this one.

I seem to have solved it but I don’t know why it now works.

Your question prompted me to actually try setting the crossorigin property on the images in the selector I described earlier … even though the images in the selector work just fine.

And as a result the textureLoader now works even without the console up. The only link between an image element in the selector and the three.js textureloader is that I call the texture loader within the click handler of the image element.

Somehow this is making the difference.

Interestingly - it seems to work just fine with .jpg files but I have one .gif and it throws a CORS error. It is an animated gif so maybe. Not an issue so much as we don’t use gifs but weird either way.

It seems like there are some fundamental bugs in the way the browser is deciding to include credentials.

If you think it’s a browser issue, I suggest you file a bug at one of the browser issue trackers:


Good idea.