在 POST 请求中使用 Angular 和 Yii2 的 CORS 错误

Posted

技术标签:

【中文标题】在 POST 请求中使用 Angular 和 Yii2 的 CORS 错误【英文标题】:CORS Error using Angular and Yii2 on POST Request 【发布时间】:2021-11-06 04:27:38 【问题描述】:

我正在创建一个使用 Angular 作为前端并使用 Yii2 作为 API 的项目。 GET请求没有任何问题。我可以顺利获取数据。问题是当我想要一个 POST 请求时。我检查了 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' => \yii\filters\Cors::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】:

请在行为中为 yii 配置 CORS,并确保允许 OPTIONS 动作/动词。你应该像这里一样添加它

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

另请参阅此处的文档:CORS config

即:

public function behaviors()

    $behaviors = parent::behaviors();

    $behaviors['corsFilter'] = [
        'class' => \yii\filters\Cors::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' => \yii\filters\Cors::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;

【讨论】:

以上是关于在 POST 请求中使用 Angular 和 Yii2 的 CORS 错误的主要内容,如果未能解决你的问题,请参考以下文章

从http post请求下载文件 - Angular 6

Angular2 不在 POST 请求中传递参数

使用 $http.post (angular) 和 bodyparser.text() 发送字符串请求时,请求正文作为对象返回?

如何在 Angular 4 Universal 中发出 http post 请求?

Angular HTTP Post 请求,Payload 嵌套在 JSON 对象中

Angular 和 Spring 启动 - POST 请求成为 OPTIONS