When using the WordPress REST API within a JavaScript application, you might encounter an error like this:
Access to XMLHttpRequest at 'https://wordpress.dev/wp-json/wp/v2/posts' from origin 'http://localapp.test' has been blocked by CORS policy: Request header field x-requested-with is not allowed by Access-Control-Allow-Headers in preflight response.
Most CORS issues can be solved by adding the following to your .htaccess
file:
Header add Access-Control-Allow-Origin "*"
However, when you try the REST API request again from your application, you’ll get a new error.
'Access-Control-Allow-Origin' header contains multiple values 'http://localapp.test, *', but only one is allowed
But why? The .htaccess rule we added from above only has a single value. The reason for this is that the WordPress REST API is already setting CORS headers using the rest_send_cors_headers()
function. You can override this by removing the existing CORS headers provided by WordPress and defining your own.
Add the following to your functions.php
file:
function my_custom_rest_cors() {
remove_filter( 'rest_pre_serve_request', 'rest_send_cors_headers' );
add_filter( 'rest_pre_serve_request', function( $value ) {
header( 'Access-Control-Allow-Origin: *' );
header( 'Access-Control-Allow-Methods: GET' );
header( 'Access-Control-Allow-Credentials: true' );
header( 'Access-Control-Expose-Headers: Link', false );
return $value;
} );
}
add_action( 'rest_api_init', 'my_custom_rest_cors', 15 );
There are lots of reasons why you wouldn’t setup the headers in the way shown above, but this is a great baseline for getting the REST API configured to play nice with Axios, jQuery.ajax()
or the Fetch API.
Hope that helps!