CORS issue with canvas only when image is preloaded

僤鯓⒐⒋嵵緔 提交于 2019-12-02 22:06:44

问题


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:


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/58523575/cors-issue-with-canvas-only-when-image-is-preloaded

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!