0

TLDR; Is there a way I can enable CORS for SVGs in my WordPress back-end, so I can get them through a http request to a different domain? Ideally without having to touch .htaccess?

What I'm aiming for

I am building a headless WordPress/React site. I would like to have my SVGs, uploaded to WP back-end, inlined into my front-end code (so I can access their DOM).

I have URL to the SVG and react-inlinesvg library allows me to inline it. I am getting No 'Access-Control-Allow-Origin' header is present on the requested resource. error however. react-inlinesvg makes the actual http request through httppleaselibrary.

What I've tried

At first, I had to enable upload of SVGs to the admin.

add_filter('upload_mimes', function($mimes) {
    return array_replace($mimes, [
        'svg' => 'image/svg+xml',
        'svgz' => 'image/svg+xml'
    ]);
});

I've found those filters as well, but I don't think they are being fired if the file is requested via http:

add_action('rest_api_init', function($wp) {
    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: POST, GET, OPTIONS, PUT, DELETE' );
        header( 'Access-Control-Allow-Credentials: true' );
        return $value;
    });
});

add_filter('wp_headers', function($headers) {
    $headers['Access-Control-Allow-Origin'] = '*';
    return $headers;
});

Thanks in advance!

1
  • I'm surprised you're serving SVGs though the REST API. Aren't they static content from /wp-content/uploads ?
    – Rup
    Feb 21 at 14:09

1 Answer 1

0

By using custom rewrite_url, I was able to hijack the request and set its CORS-friendly headers.

class Cors_Media {

    const QUERY_VAR = 'cors_media_id';

    public function init() {
        add_action('init', [$this, 'add_rewrite_rule']);
        add_filter('query_vars', [$this, 'query_vars']);
        add_action('template_redirect', [$this, 'template_redirect']);
    }

    public function query_vars(array $qs) {
        $qs[] = 'cors_media_id';
        return $qs;
    }

    public function add_rewrite_rule() {
        add_rewrite_rule(
            '^cors_media_id/([0-9]+)/?',
            'index.php?cors_media_id=$matches[1]',
            'top'
        );
    }

    public function template_redirect() {
        $att_id = get_query_var('cors_media_id');
        if (empty($att_id)) { return; }
        $url = wp_get_attachment_url($att_id);
        if ($url) {
            $this->show_file($url);
        }
        exit;
    }

    protected function show_file($url) {
        header('Access-Control-Allow-Origin: *');
        echo file_get_contents($url);
        exit;
    }

}

$obj = new Cors_Media;
$obj->init();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.