Skip to content

Instantly share code, notes, and snippets.

@casamia918
Last active February 27, 2022 02:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save casamia918/a8daf164830bce1b6281e304ed1f91b0 to your computer and use it in GitHub Desktop.
Save casamia918/a8daf164830bce1b6281e304ed1f91b0 to your computer and use it in GitHub Desktop.
How to handle canvas.toDataURL securityError

I know you are searching to resolve securityError while working with image and html canvas. You might be first encountered this solution, which saying

"Set crossOrigin='anonymous' before image.src. and use image in onload event handler" (Related SO questions: https://stackoverflow.com/questions/25753754/canvas-todataurl-security-error-the-operation-is-insecure https://stackoverflow.com/questions/20424279/canvas-todataurl-securityerror )

So, you've already tried, but failed. right?

Me too haha. Go back and erase all codes, drink all the night. Your project is fucked up.

Sorry, its humor.

In my case, the above solution is not working. In my app, image masking process is working on canvas, with userImage from server and maskImage which generated from client. These images are in different image domains, so security error can be occurs.

But actually, chrome or firefox does not throw security error, but only ie11 throws that error. I don't know why. But anyway, it has potential problem.

related articles. https://dzone.com/articles/understanding-html5-canvas https://html.spec.whatwg.org/multipage/canvas.html#security-with-canvas-elements

Finally, I found silver bullet.

Always create HTMLImageElement from source of image blob , not from image url directly.

https://developer.mozilla.org/en-US/docs/Web/API/Blob

Why use blob? It is just byte stream. So all the image header is gone. But when use image url as source, the HTMLImageElement contains image response header, and these will be used in the security check logic in the js engine.

Here is my example code

async function loadImageFromBlob(url) {

  return new Promise((resolve, reject) => {

    window.fetch(url)
      .then(resp => resp.blob())
      .then(blob => {
        const urlFromBlob = window.URL.createObjectURL(blob);

        const image = new window.Image()
        image.src = urlFromBlob;
        image.crossOrigin = 'Anonymous';
        image.addEventListener('load', () => {
          resolve(image);
        })
        image.addEventListener('error', reject);

      })

   })

}

good luck!

@barbaraperim
Copy link

window.fetch unfortunately is not compatible with ie11 https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

@JanderSilv
Copy link

Thank you so much!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment