Вопрос или проблема
Я начал небольшой проект на 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. Дополнительные шаги
-
Убедитесь, что запрашиваемый ресурс доступен: Иногда ошибка CORS может быть вызвана тем, что вы запрашиваете ресурс, который еще не существует или не должен быть доступен для обработки.
-
Тестирование через Postman: Используйте инструменты, такие как Postman, для проверки, работает ли ваш API без ограничения CORS. Это поможет определить, связано ли это с конфигурацией сервера или с клиентом.
-
Проверка конфигураций локального сервера: Если вы используете сервер разработки, такой как XAMPP или MAMP, убедитесь, что все параметры настроены правильно.
Следуя этим шагам и рекомендациям, вы должны устранить ошибку CORS и успешно взаимодействовать с API WordPress на localhost:3000
. Если возникнут дополнительные сложности, постарайтесь предоставить больше информации или логов, чтобы провести более глубокую диагностику.