Site icon WebDevStudios

Resolve CORS Errors with WordPress REST API

Cross-Origin Resource Sharing (CORS) is a relatively new problem in JavaScript development. Maybe I’m showing my age here, but I can distinctly remember when there were no concerns with loading JavaScript from all over the internet into your blog. It was new! It was fun! But as more and more of us got online, and JavaScript webpages turned into JavaScript applications, it became a huge security risk. Thus, we have our modern world where a JavaScript file can only be loaded outside of its domain if it contains the correct Access-Control-Allow-Origin headers.

So, what do you do when you’re happily making a block (as part of your agency’s Gutenberg-first initiative, of course), and the API you are trying to access doesn’t have the correct headers? Let me show you a quick way to resolve a CORS error with the WordPress REST API. In particular, we’re going to create a custom REST endpoint and proxy our request through the WordPress API.

I ran into this problem when revisiting my old custom oEmbed provider. I wanted to accomplish the same thing, but in JavaScript:

However, when trying to load the API from my local machine, I got these errors:

In short, because the remote server backend.deviantart.com is not set up to allow an arbitrary web page to load its JavaScript, I could not call the API directly from my block using fetch. To get around this, we’ll be using the PHP backend and wp_remote_get.

New REST Endpoint

First, we need to set up our custom endpoint. This will allow us to call the WordPress backend from our block:

See the gist on github.

You can read more about register_rest_route in the WordPress docs. With this code, we are setting up the following flow:

  1. Block will call /wp-json/oddevan/v1/devArtProxy/
  2. WordPress will call the proxy_deviantart_oembed_security function to find out if the current user has permissions to access this endpoint
  3. WordPress will call the proxy_deviantart_oembed function.

Next, let’s check our security function:

See the gist on github.

As you can see, it’s not very complicated. We just need to pass along whether the current user can use the editor. If the user can’t use the editor, there’s no reason for them to use our endpoint. This will prevent anonymous users (aka, “anyone on the internet”) from using our endpoint, possibly for purposes we don’t like.

Now, let’s see our proxy function:

See the gist on github.

There’s a bit going on here. First, we get the url variable from the request and run it through a helper function we wrote to make sure it is actually a DeviantArt URL. Then we use wp_remote_get to have the PHP backend make the request to DeviantArt’s oEmbed API. Because requests like this don’t have the extra considerations that a JavaScript request has, they are not usually subject to CORS. After some quick checking to make sure we have an actual response, we package up the response from DeviantArt inside a WP_REST_Response object and send it back to our block.

Inside our block, we just have to call apiFetch to have WordPress automatically set up the request to our endpoint:

See the gist on github.

Because apiFetch returns a Promise, we need to use async and await when using it. But that’s another blog post.

You can see the whole thing in action in the finished plugin. It’s built using our own WDS Block Starter!

Exit mobile version