‘http://localhost:3000’ был заблокирован политикой CORS.

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

Я начал небольшой проект на WordPress на localhost:3000.

Я создаю индивидуальный тип записи и хотел обновить данные через /wp/v2/custom_post_type/{id}

На localhost:3000 я всегда получаю следующую ошибку:

Доступ к fetch на 'http://localhost/WordPress/xxx/wp-json/wp/v2/xxx/1500?_locale=user' с источника 'http://localhost:3000' заблокирован политикой CORS: Ответ на предварительный запрос не проходит проверку доступа: Заголовок 'Access-Control-Allow-Origin' имеет значение 'http://localhost', которое не равно предоставленному источнику. Попросите сервер отправить заголовок с допустимым значением или, если непрозрачный ответ удовлетворяет ваши потребности, установите для режима запроса значение 'no-cors', чтобы получить ресурс с отключенным CORS. Понять эту ошибку
index.js:102 
        
        
       POST http://localhost/WordPress/xxx/wp-json/wp/v2/xxx/1500?_locale=user net::ERR_FAILED
defaultFetchHandler @ index.js:102
fetchAllMiddleware @ fetch-all-middleware.js:84
(анонимно) @ index.js:163
httpV1Middleware @ http-v1.js:40
(анонимно) @ index.js:163
namespaceAndEndpointMiddleware @ namespace-endpoint.js:24
(анонимно) @ index.js:163
userLocaleMiddleware @ user-locale.js:24
(анонимно) @ index.js:163
apiFetch @ index.js:168
update @ xxxMenu.js:59
(анонимно) @ MenuCard.js:641
bulkUpdatePosts @ MenuCard.js:634
uploadToCustomPostType @ MenuCard.js:647
complete @ MenuCard.js:599
parseChunk @ papaparse.min.js:7
_chunkLoaded @ papaparse.min.js:7
(анонимно) @ papaparse.min.js:7
load
stream @ papaparse.min.js:7
parse @ papaparse.min.js:7
handleImport @ MenuCard.js:504
callCallback @ react-dom.development.js:4164
invokeGuardedCallbackDev @ react-dom.development.js:4213
invokeGuardedCallback @ react-dom.development.js:4277
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:4291
executeDispatch @ react-dom.development.js:9041
processDispatchQueueItemsInOrder @ react-dom.development.js:9073
processDispatchQueue @ react-dom.development.js:9086
dispatchEventsForPlugins @ react-dom.development.js:9097
(анонимно) @ react-dom.development.js:9288
batchedUpdates$1 @ react-dom.development.js:26179
batchedUpdates @ react-dom.development.js:3991
dispatchEventForPluginEventSystem @ react-dom.development.js:9287
dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ react-dom.development.js:6465
dispatchEvent @ react-dom.development.js:6457
dispatchDiscreteEvent @ react-dom.development.js:6430Понять эту ошибку
xxxMenu.js:73 Ошибка при получении записей: {code: 'fetch_error', message: 'Вы, вероятно, оффлайн.'}

Когда я собираю свои js файлы и пробую их напрямую на своем сайте, у меня нет никаких проблем. Поэтому я хочу узнать, какие настройки мне нужно добавить, чтобы я мог тестировать API fetch на localhost:3000?

Что я сделал:

1) functions.php

function allow_cors_from_localhost($headers) {
    // Установите разрешенный источник на домен вашего фронтенда
    $headers['Access-Control-Allow-Origin'] = 'http://localhost:3000';
    $headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS';
    $headers['Access-Control-Allow-Credentials'] = 'true';
    $headers['Access-Control-Allow-Headers'] = 'Content-Type, X-WP-Nonce, Authorization';

    return $headers;
}
add_filter('rest_api_init', function () {
    add_filter('rest_pre_serve_request', function ($value) {
        header('Access-Control-Allow-Origin: http://localhost:3000');
        header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
        header('Access-Control-Allow-Credentials: true');
        header('Access-Control-Allow-Headers: Content-Type, X-WP-Nonce, Authorization');
        return $value;
    });
});

2) .htaccess

# НАЧАЛО WordPress
# Директивы (строки) между "НАЧАЛО WordPress" и "КОНЕЦ WordPress" 
# динамически генерируются и должны изменяться только через фильтры WordPress.
# Любые изменения директив между этими маркерами будут перезаписаны.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /WordPress/xxx/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /WordPress/xxx/index.php [L]
</IfModule>

# КОНЕЦ WordPress

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

Проблема, с которой вы столкнулись, связана с политикой CORS (Cross-Origin Resource Sharing). Это механизм безопасности, который блокирует запросы с одного источника (origin), если они пытаются получить доступ к ресурсам другого источника. В вашем случае, ваш фронтенд находится на http://localhost:3000, а ваш WordPress сайт — на http://localhost/WordPress/xxx. Когда вы пытаетесь выполнить запрос к API WordPress, сервер отклоняет запрос из-за несоответствия заголовка Access-Control-Allow-Origin, который необходимо правильно настроить.

Вы уже сделали несколько шагов для решения этой проблемы, но давайте рассмотрим их и добавим окончательные настройки.

1. Настройка functions.php

Ваш код в functions.php выглядит правильно, но убедитесь, что он действительно выполняется. Проверьте, нет ли ошибок в других частях вашего кода, которые могут препятствовать выполнению этой функции. Чтобы убедиться, что заголовки отправляются корректно, можно добавить вывод сообщений для отладки, чтобы проверить, вызывается ли ваш фильтр:

function allow_cors_from_localhost($headers) {
    $headers['Access-Control-Allow-Origin'] = 'http://localhost:3000';
    $headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS';
    $headers['Access-Control-Allow-Credentials'] = 'true';
    $headers['Access-Control-Allow-Headers'] = 'Content-Type, X-WP-Nonce, Authorization';
    return $headers;
}
add_filter('rest_api_init', function () {
    add_filter('rest_pre_serve_request', function ($value) {
        if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
            header('Access-Control-Allow-Origin: http://localhost:3000');
            header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
            header('Access-Control-Allow-Credentials: true');
            header('Access-Control-Allow-Headers: Content-Type, X-WP-Nonce, Authorization');
            exit; // Необходимо завершить выполнение, чтобы избежать дальнейшей обработки
        }
        return $value;
    });
});

2. .htaccess

Ваш .htaccess файл также выглядит стандартно для установки WordPress, но вы можете добавить некоторые дополнительные заголовки, чтобы убедиться, что CORS правильно настроен. Добавьте следующие строки:

<IfModule mod_headers.c>
   Header set Access-Control-Allow-Origin "http://localhost:3000"
   Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
   Header set Access-Control-Allow-Credentials "true"
   Header set Access-Control-Allow-Headers "Content-Type, X-WP-Nonce, Authorization"
</IfModule>

3. Проверка консоли и отправка запросов

После внесения изменений очистите кэш браузера и проверьте консоль разработчика (DevTools) в браузере, чтобы убедиться, что запросы к API отправляются и сервер отвечает с правильными заголовками.

4. Дополнительные шаги

  1. Убедитесь, что запрашиваемый ресурс доступен: Иногда ошибка CORS может быть вызвана тем, что вы запрашиваете ресурс, который еще не существует или не должен быть доступен для обработки.

  2. Тестирование через Postman: Используйте инструменты, такие как Postman, для проверки, работает ли ваш API без ограничения CORS. Это поможет определить, связано ли это с конфигурацией сервера или с клиентом.

  3. Проверка конфигураций локального сервера: Если вы используете сервер разработки, такой как XAMPP или MAMP, убедитесь, что все параметры настроены правильно.

Следуя этим шагам и рекомендациям, вы должны устранить ошибку CORS и успешно взаимодействовать с API WordPress на localhost:3000. Если возникнут дополнительные сложности, постарайтесь предоставить больше информации или логов, чтобы провести более глубокую диагностику.

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

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