Describe the bug
In some cases when rotating an image in the editor an error is thrown from canvas.toBlob, and the image is not rotated.
In Firefox the error is:
SecurityError: The operation is insecure.
In Google Chrome the error is:
Uncaught DOMException: Failed to execute 'toBlob' on 'HTMLCanvasElement': Tainted canvases may not be exported.
The error does not seem to happen on initial image placement—only when editing a previously placed image.
To reproduce
Steps to reproduce the behavior:
What's the URL of tithe image being edited? Usually this error happens only if the images is not on the same domain.
The image is coming from the same origin. I'm running my dev environment with Local, so I have tinker.local set up in my /etc/hosts file to point to 127.0.0.1. The post is at https://tinker.local/wp-admin/post.php?post=520&action=edit and the image is http://tinker.local/wp-content/uploads/2020/04/aerial-view-of-city-buildings-3875821-1024x684.jpg.
Edit: There appears to be a difference in http vs https. Maybe that is the problem?
Edit: There appears to be a difference in http vs https. Maybe that is the problem?
That's probably it :)
This is an issue for valid configurations as well. If images are served from e.g. a CDN with a different domain, this error is triggered.
@sirreal Are they hosted by the WordPress site? Is CORS set to be allowed?
The images are served from a different domain (example.com/wp-admin/post-new.php / files.example.com/…/image.jpg). The image requests have no special CORS headers (no Access-Control-Allow-Origin).
I'd suggest at a minimum, the block should disable whatever features aren't expected to work under these conditions (disable rotation or disable image manipulation entirely).
An enhancement would be to fall back to server-side image manipulations in case the block cannot be manipulated in the client.
Access-Control-Allow-Origin: * or Access-Control-Allow-Origin: [ site url ] headers are required for this to work with images server from a different domain.
There's also a client side change necessary. This section:
Needs to add crossOrogin as follows:
const el = new window.Image();
el.crossOrigin = ""; // Same as "Anonymous"
el.src = url;
el.onload = editImage;
There is also a case where images may require authentication. In that case the change would be
const el = new window.Image();
el.crossOrigin = "use-credentials";
el.src = url;
el.onload = editImage;
and the HTTP header Access-Control-Allow-Credentials: true is necessary.
See MDN Docs on this.