Starting from Headless Wordpress Starter Kit I am taking two images from the Wordpress media library and drawing them onto a html5 canvas element which I need people to be able to save as an image.
Since the domain of the head is different from the back I will get the error of tainted cross-origin requests. So I set crossOrigin
to anonymous
. Here is the code where I draw the image to the canvas.
Logo
const image = new Image();
image.setAttribute("crossOrigin", "anonymous");
image.width = logo[size].width;
image.height = logo[size].height;
image.src = `${logo[size].source_url}`;
image.onload = () => {
const x = (this.width - image.width) / 2;
this._ctx.drawImage(image, x, x, image.width, image.height);
};
Background Image
const image = new Image(this.width, this.height);
image.setAttribute("crossOrigin", "anonymous");
image.src = backgroundImage[size].source_url;
image.onload = () => {
const x = image.width / 2;
this._ctx.drawImage(image, -x, 0);
};
Server / Backend
I didn't edit the CORS set by theme provided in the starter kit.
wp-content/themes/postlight-headless-wp/inc/cors.php
remove_filter( 'rest_pre_serve_request', 'rest_send_cors_headers' );
add_filter( 'rest_pre_serve_request', function ( $value ) {
header( 'Access-Control-Allow-Origin: ' . get_frontend_origin() );
header( 'Access-Control-Allow-Methods: GET' );
header( 'Access-Control-Allow-Credentials: true' );
return $value;
});
I figured since I was requesting the files directly this script shouldn't be invoked by the server.
Instead I setup a couple docker containers to run a lamp stack. Here's the docker-compose.yaml
.
version: "2"
services:
db:
container_name: database
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
ports: # Set up ports exposed for other containers to connect to
- "3306:3306"
environment: # Set up mysql database name and password
MYSQL_ROOT_PASSWORD: **********
MYSQL_DATABASE: **********
MYSQL_USER: **********
MYSQL_PASSWORD: **********
wordpress:
build: .
container_name: wordpress
depends_on:
- db
ports:
- "4000:80"
volumes:
- ./html:/var/www/html
links:
- db
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_PASSWORD: **********
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: phpmyadmin
depends_on:
- db
restart: always
ports:
- "8080:80"
environment:
- PMA_ARBITRARY=1
volumes:
db_data:
At the root of the html folder I added the .htaccess
file.
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
<FilesMatch "\.(bmp|cur|gif|ico|jpe?g|png|svgz?|webp)$">
SetEnvIf Origin ":" IS_CORS
Header set Access-Control-Allow-Origin "*" env=IS_CORS
</FilesMatch>
</IfModule>
</IfModule>
# END WordPress
With all of this I expected that I wouldn't have a problem. But I'm here, and I've typed all this, so, yeah, I have a problem. The background images work perfectly, the logo images don't.
Chrome 70 - Nope.
Access to image at 'http://localhost:4000/wp-content/uploads/2018/10/paintWithNoBackground-1-150x150.png' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Safari 12 - Nope.
[Error] Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin.
[Error] Cannot load image http://localhost:4000/wp-content/uploads/2018/10/paintWithNoBackground-1-150x150.png due to access control checks.
[Error] Failed to load resource: Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin. (paintWithNoBackground-1-150x150.png, line 0)
Firefox 63 - Yes, it works here
No errors.
In all browsers the background image works just fine. I don't know why one would work and the other not, and then why it works in Firefox but not Chrome, or Safari. Let me know if you need any other information.