Ошибка CORS с использованием углового и Yii2 по запросу POST

#php #angular #yii2 #cors

Вопрос:

Я создаю проект, используя Angular в качестве интерфейса и используя Yii2 для API. У него нет никаких проблем с получением запроса. Я могу легко получить данные. Проблема в том, когда я хочу получить запрос на публикацию. Я проверил запрос на вкладке «Сеть» инструментов разработки chrome и увидел два запроса: один со статусом ошибки CORS и один со значением 405.

Вот мой код:

Интерфейс (Угловой)

 addRecipe(recipe: Recipe) {
  this.http
    .post('https://the-url-to-my-api', recipe, {
      headers: new HttpHeaders({
        'Origin': '*',
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Credentials': 'true'
      })
    })
    .subscribe(response => {
      console.log(response);
    });
}
 

Класс и функции Yii2

 class RecipeController extends ActiveController
{
    public function actions() {
        $actions = parent::actions();

        unset(
            $actions[ 'index' ],
            $actions[ 'create' ],
            $actions[ 'update' ],
            $actions[ 'delete' ]
        );


        return $actions;
    }

    protected function verbs()
    {
        return [
            'index' => ['GET', 'HEAD'],
            'view' => ['GET', 'HEAD'],
            'create' => ['POST'],
            'update' => ['POST', 'PUT', 'PATCH'],
            'delete' => ['DELETE'],
            'login' => ['POST'],
            'find' => ['GET'],
        ];
    }
 

Поведение Yii2

 public function behaviors()
{
    $behaviors = parent::behaviors();

    // remove authentication filter
    $auth = $behaviors['authenticator'];
    unset($behaviors['authenticator']);

    // add CORS filter
    $behaviors['corsFilter'] = [
        'class' => yiifiltersCors::className(),
        // 'cors' => [
        //     'Access-Control-Allow-Origin' => ['http://localhost:4200'],
        //     'Access-Control-Request-Method' => ['OPTIONS', 'GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
        //     'Access-Control-Request-Headers' => ['*'],
        //     'Access-Control-Allow-Credentials' => true,
        //     'Access-Control-Max-Age' => 86400,
        //     'Access-Control-Expose-Headers' => [],
        // ]
    ];

    // re-add authentication filter
    $behaviors['authenticator'] = $auth;
    // avoid authentication on CORS-pre-flight requests (HTTP OPTIONS method)
    $behaviors['authenticator']['except'] = ['options'];

    return $behaviors;
}
 

Yii2 htaccess

 Header set Access-Control-Allow-Origin 'http://localhost:4200'
Header always set Access-Control-Allow-Methods "POST, GET, DELETE, PUT"
Header always set Access-Control-Allow-Headers "*"
 

Я проверил везде и перепробовал много вещей, но я все равно получил эту ошибку CORS. Есть ли что-то, чего мне не хватает на стороне сервера?

Ответ №1:

Пожалуйста, настройте CORS для yii в поведении и, пожалуйста, убедитесь, что OPTIONS действие/глагол разрешены. Вы должны добавить его, как здесь

 'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
 

Смотрите также документы здесь: Конфигурация CORS

то есть:

 public function behaviors()
{
    $behaviors = parent::behaviors();

    $behaviors['corsFilter'] = [
        'class' => yiifiltersCors::className(),
        'cors' => [
            'Origin' => ['*'],
            'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
            'Access-Control-Request-Headers' => ['*'],
            'Access-Control-Allow-Methods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
            'Allow' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
            'Access-Control-Allow-Credentials' => null,
            'Access-Control-Max-Age' => 86400,
            'Access-Control-Expose-Headers' => []
        ]

    ];
    return $behaviors;
}
 

Ответ №2:

Это проблема с вашим бэкэндом(Yii2). Попробуйте использовать этот код

 public function behaviors()
{
    $behaviors = parent::behaviors();

    $behaviors['corsFilter'] = [
        'class' => yiifiltersCors::className(),
        'cors' => [
            'Origin' => ['*'],
            // 'Access-Control-Allow-Origin' => ['*'],
            'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
            'Access-Control-Request-Headers' => ['*'],
            'Access-Control-Allow-Credentials' => null,
            'Access-Control-Max-Age' => 86400,
            'Access-Control-Expose-Headers' => []
        ]

    ];
    return $behaviors;
}