Вопрос или проблема
Кратко: Есть ли способ включить 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-файлам за пределами вашего основного домена.
Шаги для решения проблемы
-
Разрешение загрузки SVG в WordPress:
Вам уже удалось разрешить загрузку SVG-файлов. Позаботьтесь о том, чтобы этот код был добавлен в файл функций вашей темы (functions.php
):add_filter('upload_mimes', function($mimes) { return array_replace($mimes, [ 'svg' => 'image/svg+xml', 'svgz' => 'image/svg+xml' ]); });
-
Настройка 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; });
-
Создание промежуточного обработчика 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". Это позволит привлечь больше трафика на вашу статью и обеспечить её популярность среди разработчиков.