Ошибка "Response to preflight request doesn't pass access control check" (Предварительный запрос не прошел проверку контроля доступа) возникает, когда клиентский код пытается отправить AJAX-запрос на сервер, который работает на другом домене или на другом порту, и сервер не разрешил такие запросы с помощью политики Access-Control-Allow-Origin.
Политика "Same-Origin" была создана для улучшения безопасности браузера, и ограничивает доступ к ресурсам между разными доменами. Запросы сделанные с одного источника (домена/порта/протокола) могут безопасно делать запросы на тот же самый источник, тогда как запросы сделанные с другого источника требуют дополнительных проверок.
Для разрешения этой ошибки в Yii2 необходимо настроить CORS (Cross-Origin Resource Sharing). Для этого вам понадобится сделать следующие шаги:
1. Создайте специальный класс-фильтр, который будет обрабатывать запросы от разных источников. Например:
namespace appfilters; use yiibaseActionFilter; class CorsFilter extends ActionFilter { public function beforeAction($action) { $allowedOrigins = ['http://example.com', 'http://localhost']; // проверяем, является ли источник запроса одним из разрешенных $origin = Yii::$app->request->getHeaders()->get('Origin'); if (in_array($origin, $allowedOrigins)) { Yii::$app->response->headers->add('Access-Control-Allow-Origin', $origin); Yii::$app->response->headers->add('Access-Control-Allow-Credentials', 'true'); } return parent::beforeAction($action); } }
2. Зарегистрируйте созданный фильтр в config/web.php
:
return [ // ... 'components' => [ // ... ], 'as cors' => [ 'class' => 'appfiltersCorsFilter', ], // ... ];
3. Включите CORS-заголовки в настройках вашего web
-компонента в config/web.php
:
return [ // ... 'components' => [ 'response' => [ 'format' => yiiwebResponse::FORMAT_JSON, 'charset' => 'UTF-8', 'on beforeSend' => function ($event) { $headers = $event->sender->headers; $headers->add('Access-Control-Allow-Origin', '*'); $headers->add('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); $headers->add('Access-Control-Allow-Headers', 'Accept, Content-Type, X-Requested-With'); $event->sender->format = yiiwebResponse::FORMAT_JSON; return $event->sender; }, ], // ... ], // ... ];
Теперь ваш сервер Yii2 будет разрешать AJAX-запросы от любого источника. Обратите внимание, что во втором шаге вы можете определить список разрешенных источников в allowedOrigins
, чтобы ограничить доступ только к определенным источникам.