Reputation: 4705
My issue only arises when the loaded image was preloaded somewhere else. For example, when I somewhere use a <img>
-tag with the src
attribute.
Have a look at this code:
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;" ></canvas>
<img src="https://local-spaces.fra1.digitaloceanspaces.com/test.jpg" width="50"/>
<button onclick="show()">Load Canvas Picture</button>
<script>
function show() {
const c = document.getElementById("myCanvas");
const ctx = c.getContext("2d");
const img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.onload = function(){
ctx.drawImage(img,0,0, 300, 150);
};
img.src = "https://local-spaces.fra1.digitaloceanspaces.com/test.jpg"
}
</script>
Note: If you are seeing the image in canvas correctly, please cache+hardreload your browser to see the error.
If you are clicking on the button and open your console, you will see that you are getting a CORS-error:
Access to image at 'https://local-spaces.fra1.digitaloceanspaces.com/test.jpg' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Now let's take the next example to see that it is working without preloading the image: https://jsfiddle.net/akzxp9vs/
Note: To make this example work, it's super important that you are deleting your cache + hard reload your browser.
Only then you see that the correct header response is giving back.
Any ideas what I can do?
The image is on the S3 Cloud of Digital Ocean, called Spaces. The image itself is set to public and the CORS setting are set to:
Upvotes: 3
Views: 2321
Reputation: 4705
I found a better solution to my problem. @Quentin's solution is principally right, but it's just not practicable. I tried to update all <img>
-tags, however in my page I have dozens of packages that are using the <img>
-tag as well.
For example Leaflet. It's like Google Maps, but with Open Street Maps. You just don't have the control over to set attributes like crossorigin
in custom icons.
So there had to be another solution. It feels bad to use it, but it does the job.
const src = new URL(imgUrl);
src.searchParams.append('cors', Date.now());
return src.href;
This code appends to your URL a query parameter and forces Chrome to reload the image without being cached.
Upvotes: 0
Reputation: 943615
The browser needs to know to check for CORS permissions when the HTTP request is made (i.e. to include an Origin
header etc).
When you create a new Image
object, it uses the cached data from the <img>
element.
Add a crossorigin
attribute to the existing <img>
element or remove that <img>
element entirely.
Upvotes: 3