Включите CORS для получения встроенного SVG по URL

Вопрос или проблема

Кратко: Есть ли способ включить CORS для SVG в моем бэкенде WordPress, чтобы я мог получить их через http-запрос к другому домену? Желательно без внесения изменений в .htaccess?

Что я хочу достичь

Я создаю безголовый сайт на WordPress/React. Я хотел бы инлайнить свои SVG, загруженные в бэкенд WP, в мой фронтенд-код (чтобы иметь возможность получить доступ к их DOM).

У меня есть URL на SVG, и библиотека react-inlinesvg позволяет мне встраивать его. Однако я получаю ошибку No 'Access-Control-Allow-Origin' header is present on the requested resource.. Библиотека react-inlinesvg делает фактический http-запрос через библиотеку httpplease.

Что я пробовал

Сначала мне пришлось разрешить загрузку SVG в админке.

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

Я нашел и эти фильтры, но не думаю, что они срабатывают, если файл запрашивается через 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;
});

Спасибо заранее!

Используя пользовательский rewrite_url, я смог перехватить запрос и установить его заголовки, совместимые с CORS.

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();

Ответ или решение

Включение CORS для получения встроенных SVG через URL в WordPress

Введение

Вам необходимо позволить кросс-доменные запросы (CORS) для SVG-файлов, загруженных в бэкэнд WordPress, чтобы можно было интегрировать их в ваше React-приложение без ошибок доступа. В этой статье мы подробно рассмотрим решение вашей задачи, избегая изменений в файле .htaccess.

Почему CORS важен?

CORS — это механизм, который позволяет веб-приложениям безопасно запрашивать ресурсы на других доменах. Если CORS не настроен правильно, вы получите сообщение об ошибке: "No ‘Access-Control-Allow-Origin’ header is present on the requested resource", когда ваше приложение будет пытаться получить доступ к SVG-файлам за пределами вашего основного домена.

Шаги для решения проблемы

  1. Разрешение загрузки SVG в WordPress:
    Вам уже удалось разрешить загрузку SVG-файлов. Позаботьтесь о том, чтобы этот код был добавлен в файл функций вашей темы (functions.php):

    add_filter('upload_mimes', function($mimes) {
       return array_replace($mimes, [
           'svg' => 'image/svg+xml',
           'svgz' => 'image/svg+xml'
       ]);
    });
  2. Настройка CORS через REST API:
    Вы можете настроить заголовки CORS через REST API. Однако, факторов, которые могут помешать срабатыванию данных фильтров, много. Убедитесь, что они применяются должным образом, используя следующий кусок кода:

    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;
    });
  3. Создание промежуточного обработчика CORS:
    Учитывая, что предыдущие методы могут не срабатывать в некоторых современных конфигурациях, вы разработали класс Cors_Media, который использует перезапись URL для управления заголовками CORS более гибким образом:

    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();

    Этот класс создает специальный маршрут для получения SVG-файла, позволяя установить необходимые CORS заголовки.

Заключение

С помощью представленного кода вы сможете успешно интегрировать SVG-файлы в ваше React-приложение без необходимости вносить изменения в файл .htaccess. Не забудьте протестировать ваше решение, чтобы убедиться, что запросы выполняются успешно и CORS заголовки корректно установлены.

Этот метод обеспечивает чистоту кода и минимальное вмешательство в базовые настройки сервера, что может упростить дальнейшую поддержку вашего проекта.

SEO Оптимизация

Для улучшения видимости данной информации в поисковых системах оптимизируйте заголовки, подзаголовки и темы с использованием ключевых слов, таких как "CORS для SVG в WordPress", "интеграция SVG в React", "разрешения CORS в WordPress". Это позволит привлечь больше трафика на вашу статью и обеспечить её популярность среди разработчиков.

Оцените материал
Добавить комментарий

Капча загружается...